aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
commit5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch)
treea6140557876943cdd800ee997c9317283394b22c /lib/Bitcode
parentf03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff)
downloadsrc-5a5ac124e1efaf208671f01c46edb15f29ed2a0b.tar.gz
src-5a5ac124e1efaf208671f01c46edb15f29ed2a0b.zip
Notes
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp1267
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h365
-rw-r--r--lib/Bitcode/Reader/BitstreamReader.cpp40
-rw-r--r--lib/Bitcode/Reader/CMakeLists.txt3
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp595
-rw-r--r--lib/Bitcode/Writer/BitcodeWriterPass.cpp16
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp39
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h25
8 files changed, 1698 insertions, 652 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 3d9546fc2b79..f6d5ccc1a59e 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -8,32 +8,380 @@
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/ReaderWriter.h"
-#include "BitcodeReader.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/DataStream.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
-
+#include <deque>
using namespace llvm;
+namespace {
enum {
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
};
+class BitcodeReaderValueList {
+ std::vector<WeakVH> ValuePtrs;
+
+ /// ResolveConstants - As we resolve forward-referenced constants, we add
+ /// information about them to this vector. This allows us to resolve them in
+ /// bulk instead of resolving each reference at a time. See the code in
+ /// ResolveConstantForwardRefs for more information about this.
+ ///
+ /// The key of this vector is the placeholder constant, the value is the slot
+ /// number that holds the resolved value.
+ typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
+ ResolveConstantsTy ResolveConstants;
+ LLVMContext &Context;
+public:
+ BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
+ ~BitcodeReaderValueList() {
+ assert(ResolveConstants.empty() && "Constants not resolved?");
+ }
+
+ // vector compatibility methods
+ unsigned size() const { return ValuePtrs.size(); }
+ void resize(unsigned N) { ValuePtrs.resize(N); }
+ void push_back(Value *V) {
+ ValuePtrs.push_back(V);
+ }
+
+ void clear() {
+ assert(ResolveConstants.empty() && "Constants not resolved?");
+ ValuePtrs.clear();
+ }
+
+ Value *operator[](unsigned i) const {
+ assert(i < ValuePtrs.size());
+ return ValuePtrs[i];
+ }
+
+ Value *back() const { return ValuePtrs.back(); }
+ void pop_back() { ValuePtrs.pop_back(); }
+ bool empty() const { return ValuePtrs.empty(); }
+ void shrinkTo(unsigned N) {
+ assert(N <= size() && "Invalid shrinkTo request!");
+ ValuePtrs.resize(N);
+ }
+
+ Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
+ Value *getValueFwdRef(unsigned Idx, Type *Ty);
+
+ void AssignValue(Value *V, unsigned Idx);
+
+ /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+ /// resolves any forward references.
+ void ResolveConstantForwardRefs();
+};
+
+class BitcodeReaderMDValueList {
+ unsigned NumFwdRefs;
+ bool AnyFwdRefs;
+ unsigned MinFwdRef;
+ unsigned MaxFwdRef;
+ std::vector<TrackingMDRef> MDValuePtrs;
+
+ LLVMContext &Context;
+public:
+ BitcodeReaderMDValueList(LLVMContext &C)
+ : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
+
+ // vector compatibility methods
+ unsigned size() const { return MDValuePtrs.size(); }
+ void resize(unsigned N) { MDValuePtrs.resize(N); }
+ void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); }
+ void clear() { MDValuePtrs.clear(); }
+ Metadata *back() const { return MDValuePtrs.back(); }
+ void pop_back() { MDValuePtrs.pop_back(); }
+ bool empty() const { return MDValuePtrs.empty(); }
+
+ Metadata *operator[](unsigned i) const {
+ assert(i < MDValuePtrs.size());
+ return MDValuePtrs[i];
+ }
+
+ void shrinkTo(unsigned N) {
+ assert(N <= size() && "Invalid shrinkTo request!");
+ MDValuePtrs.resize(N);
+ }
+
+ Metadata *getValueFwdRef(unsigned Idx);
+ void AssignValue(Metadata *MD, unsigned Idx);
+ void tryToResolveCycles();
+};
+
+class BitcodeReader : public GVMaterializer {
+ LLVMContext &Context;
+ DiagnosticHandlerFunction DiagnosticHandler;
+ Module *TheModule;
+ std::unique_ptr<MemoryBuffer> Buffer;
+ std::unique_ptr<BitstreamReader> StreamFile;
+ BitstreamCursor Stream;
+ DataStreamer *LazyStreamer;
+ uint64_t NextUnreadBit;
+ bool SeenValueSymbolTable;
+
+ std::vector<Type*> TypeList;
+ BitcodeReaderValueList ValueList;
+ BitcodeReaderMDValueList MDValueList;
+ std::vector<Comdat *> ComdatList;
+ SmallVector<Instruction *, 64> InstructionList;
+
+ std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+ std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
+
+ SmallVector<Instruction*, 64> InstsWithTBAATag;
+
+ /// MAttributes - The set of attributes by index. Index zero in the
+ /// file is for null, and is thus not represented here. As such all indices
+ /// are off by one.
+ std::vector<AttributeSet> MAttributes;
+
+ /// \brief The set of attribute groups.
+ std::map<unsigned, AttributeSet> MAttributeGroups;
+
+ /// FunctionBBs - While parsing a function body, this is a list of the basic
+ /// blocks for the function.
+ std::vector<BasicBlock*> FunctionBBs;
+
+ // When reading the module header, this list is populated with functions that
+ // have bodies later in the file.
+ std::vector<Function*> FunctionsWithBodies;
+
+ // When intrinsic functions are encountered which require upgrading they are
+ // stored here with their replacement function.
+ typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
+ UpgradedIntrinsicMap UpgradedIntrinsics;
+
+ // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
+ DenseMap<unsigned, unsigned> MDKindMap;
+
+ // Several operations happen after the module header has been read, but
+ // before function bodies are processed. This keeps track of whether
+ // we've done this yet.
+ bool SeenFirstFunctionBody;
+
+ /// DeferredFunctionInfo - When function bodies are initially scanned, this
+ /// map contains info about where to find deferred function body in the
+ /// stream.
+ DenseMap<Function*, uint64_t> DeferredFunctionInfo;
+
+ /// When Metadata block is initially scanned when parsing the module, we may
+ /// choose to defer parsing of the metadata. This vector contains info about
+ /// which Metadata blocks are deferred.
+ std::vector<uint64_t> DeferredMetadataInfo;
+
+ /// These are basic blocks forward-referenced by block addresses. They are
+ /// inserted lazily into functions when they're loaded. The basic block ID is
+ /// its index into the vector.
+ DenseMap<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs;
+ std::deque<Function *> BasicBlockFwdRefQueue;
+
+ /// UseRelativeIDs - Indicates that we are using a new encoding for
+ /// instruction operands where most operands in the current
+ /// FUNCTION_BLOCK are encoded relative to the instruction number,
+ /// for a more compact encoding. Some instruction operands are not
+ /// relative to the instruction ID: basic block numbers, and types.
+ /// Once the old style function blocks have been phased out, we would
+ /// not need this flag.
+ bool UseRelativeIDs;
+
+ /// True if all functions will be materialized, negating the need to process
+ /// (e.g.) blockaddress forward references.
+ bool WillMaterializeAllForwardRefs;
+
+ /// Functions that have block addresses taken. This is usually empty.
+ SmallPtrSet<const Function *, 4> BlockAddressesTaken;
+
+ /// True if any Metadata block has been materialized.
+ bool IsMetadataMaterialized;
+
+ bool StripDebugInfo = false;
+
+public:
+ std::error_code Error(BitcodeError E, const Twine &Message);
+ std::error_code Error(BitcodeError E);
+ std::error_code Error(const Twine &Message);
+
+ explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+ DiagnosticHandlerFunction DiagnosticHandler);
+ explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C,
+ DiagnosticHandlerFunction DiagnosticHandler);
+ ~BitcodeReader() override { FreeState(); }
+
+ std::error_code materializeForwardReferencedFunctions();
+
+ void FreeState();
+
+ void releaseBuffer();
+
+ bool isDematerializable(const GlobalValue *GV) const override;
+ std::error_code materialize(GlobalValue *GV) override;
+ std::error_code materializeModule(Module *M) override;
+ std::vector<StructType *> getIdentifiedStructTypes() const override;
+ void dematerialize(GlobalValue *GV) override;
+
+ /// @brief Main interface to parsing a bitcode buffer.
+ /// @returns true if an error occurred.
+ std::error_code ParseBitcodeInto(Module *M,
+ bool ShouldLazyLoadMetadata = false);
+
+ /// @brief Cheap mechanism to just extract module triple
+ /// @returns true if an error occurred.
+ ErrorOr<std::string> parseTriple();
+
+ static uint64_t decodeSignRotatedValue(uint64_t V);
+
+ /// Materialize any deferred Metadata block.
+ std::error_code materializeMetadata() override;
+
+ void setStripDebugInfo() override;
+
+private:
+ std::vector<StructType *> IdentifiedStructTypes;
+ StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
+ StructType *createIdentifiedStructType(LLVMContext &Context);
+
+ Type *getTypeByID(unsigned ID);
+ Value *getFnValueByID(unsigned ID, Type *Ty) {
+ if (Ty && Ty->isMetadataTy())
+ return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
+ return ValueList.getValueFwdRef(ID, Ty);
+ }
+ Metadata *getFnMetadataByID(unsigned ID) {
+ return MDValueList.getValueFwdRef(ID);
+ }
+ BasicBlock *getBasicBlock(unsigned ID) const {
+ if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID
+ return FunctionBBs[ID];
+ }
+ AttributeSet getAttributes(unsigned i) const {
+ if (i-1 < MAttributes.size())
+ return MAttributes[i-1];
+ return AttributeSet();
+ }
+
+ /// getValueTypePair - Read a value/type pair out of the specified record from
+ /// slot 'Slot'. Increment Slot past the number of slots used in the record.
+ /// Return true on failure.
+ bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+ unsigned InstNum, Value *&ResVal) {
+ if (Slot == Record.size()) return true;
+ unsigned ValNo = (unsigned)Record[Slot++];
+ // Adjust the ValNo, if it was encoded relative to the InstNum.
+ if (UseRelativeIDs)
+ ValNo = InstNum - ValNo;
+ if (ValNo < InstNum) {
+ // If this is not a forward reference, just return the value we already
+ // have.
+ ResVal = getFnValueByID(ValNo, nullptr);
+ return ResVal == nullptr;
+ }
+ if (Slot == Record.size())
+ return true;
+
+ unsigned TypeNo = (unsigned)Record[Slot++];
+ ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
+ return ResVal == nullptr;
+ }
+
+ /// popValue - Read a value out of the specified record from slot 'Slot'.
+ /// Increment Slot past the number of slots used by the value in the record.
+ /// Return true if there is an error.
+ bool popValue(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+ unsigned InstNum, Type *Ty, Value *&ResVal) {
+ if (getValue(Record, Slot, InstNum, Ty, ResVal))
+ return true;
+ // All values currently take a single record slot.
+ ++Slot;
+ return false;
+ }
+
+ /// getValue -- Like popValue, but does not increment the Slot number.
+ bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty, Value *&ResVal) {
+ ResVal = getValue(Record, Slot, InstNum, Ty);
+ return ResVal == nullptr;
+ }
+
+ /// getValue -- Version of getValue that returns ResVal directly,
+ /// or 0 if there is an error.
+ Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty) {
+ if (Slot == Record.size()) return nullptr;
+ unsigned ValNo = (unsigned)Record[Slot];
+ // Adjust the ValNo, if it was encoded relative to the InstNum.
+ if (UseRelativeIDs)
+ ValNo = InstNum - ValNo;
+ return getFnValueByID(ValNo, Ty);
+ }
+
+ /// getValueSigned -- Like getValue, but decodes signed VBRs.
+ Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty) {
+ if (Slot == Record.size()) return nullptr;
+ unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
+ // Adjust the ValNo, if it was encoded relative to the InstNum.
+ if (UseRelativeIDs)
+ ValNo = InstNum - ValNo;
+ return getFnValueByID(ValNo, Ty);
+ }
+
+ /// Converts alignment exponent (i.e. power of two (or zero)) to the
+ /// corresponding alignment to use. If alignment is too large, returns
+ /// a corresponding error code.
+ std::error_code parseAlignmentValue(uint64_t Exponent, unsigned &Alignment);
+ std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
+ std::error_code ParseModule(bool Resume, bool ShouldLazyLoadMetadata = false);
+ std::error_code ParseAttributeBlock();
+ std::error_code ParseAttributeGroupBlock();
+ std::error_code ParseTypeTable();
+ std::error_code ParseTypeTableBody();
+
+ std::error_code ParseValueSymbolTable();
+ std::error_code ParseConstants();
+ std::error_code RememberAndSkipFunctionBody();
+ /// Save the positions of the Metadata blocks and skip parsing the blocks.
+ std::error_code rememberAndSkipMetadata();
+ std::error_code ParseFunctionBody(Function *F);
+ std::error_code GlobalCleanup();
+ std::error_code ResolveGlobalAndAliasInits();
+ std::error_code ParseMetadata();
+ std::error_code ParseMetadataAttachment(Function &F);
+ ErrorOr<std::string> parseModuleTriple();
+ std::error_code ParseUseLists();
+ std::error_code InitStream();
+ std::error_code InitStreamFromBuffer();
+ std::error_code InitLazyStream();
+ std::error_code FindFunctionInStream(
+ Function *F,
+ DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator);
+};
+} // namespace
+
BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC,
DiagnosticSeverity Severity,
const Twine &Msg)
@@ -53,6 +401,12 @@ static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler,
return Error(DiagnosticHandler, EC, EC.message());
}
+static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler,
+ const Twine &Message) {
+ return Error(DiagnosticHandler,
+ make_error_code(BitcodeError::CorruptedBitcode), Message);
+}
+
std::error_code BitcodeReader::Error(BitcodeError E, const Twine &Message) {
return ::Error(DiagnosticHandler, make_error_code(E), Message);
}
@@ -79,7 +433,7 @@ BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {}
BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C,
DiagnosticHandlerFunction DiagnosticHandler)
@@ -87,7 +441,7 @@ BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C,
TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer),
NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {}
std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
if (WillMaterializeAllForwardRefs)
@@ -133,6 +487,7 @@ void BitcodeReader::FreeState() {
std::vector<BasicBlock*>().swap(FunctionBBs);
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
+ DeferredMetadataInfo.clear();
MDKindMap.clear();
assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references");
@@ -156,19 +511,27 @@ static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
return false;
}
+static bool hasImplicitComdat(size_t Val) {
+ switch (Val) {
+ default:
+ return false;
+ case 1: // Old WeakAnyLinkage
+ case 4: // Old LinkOnceAnyLinkage
+ case 10: // Old WeakODRLinkage
+ case 11: // Old LinkOnceODRLinkage
+ return true;
+ }
+}
+
static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
switch (Val) {
default: // Map unknown/new linkages to external
case 0:
return GlobalValue::ExternalLinkage;
- case 1:
- return GlobalValue::WeakAnyLinkage;
case 2:
return GlobalValue::AppendingLinkage;
case 3:
return GlobalValue::InternalLinkage;
- case 4:
- return GlobalValue::LinkOnceAnyLinkage;
case 5:
return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
case 6:
@@ -179,10 +542,6 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
return GlobalValue::CommonLinkage;
case 9:
return GlobalValue::PrivateLinkage;
- case 10:
- return GlobalValue::WeakODRLinkage;
- case 11:
- return GlobalValue::LinkOnceODRLinkage;
case 12:
return GlobalValue::AvailableExternallyLinkage;
case 13:
@@ -191,6 +550,18 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateWeakLinkage
case 15:
return GlobalValue::ExternalLinkage; // Obsolete LinkOnceODRAutoHideLinkage
+ case 1: // Old value with implicit comdat.
+ case 16:
+ return GlobalValue::WeakAnyLinkage;
+ case 10: // Old value with implicit comdat.
+ case 17:
+ return GlobalValue::WeakODRLinkage;
+ case 4: // Old value with implicit comdat.
+ case 18:
+ return GlobalValue::LinkOnceAnyLinkage;
+ case 11: // Old value with implicit comdat.
+ case 19:
+ return GlobalValue::LinkOnceODRLinkage;
}
}
@@ -242,27 +613,42 @@ static int GetDecodedCastOpcode(unsigned Val) {
case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast;
}
}
+
static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
+ bool IsFP = Ty->isFPOrFPVectorTy();
+ // BinOps are only valid for int/fp or vector of int/fp types
+ if (!IsFP && !Ty->isIntOrIntVectorTy())
+ return -1;
+
switch (Val) {
- default: return -1;
+ default:
+ return -1;
case bitc::BINOP_ADD:
- return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
+ return IsFP ? Instruction::FAdd : Instruction::Add;
case bitc::BINOP_SUB:
- return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
+ return IsFP ? Instruction::FSub : Instruction::Sub;
case bitc::BINOP_MUL:
- return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
- case bitc::BINOP_UDIV: return Instruction::UDiv;
+ return IsFP ? Instruction::FMul : Instruction::Mul;
+ case bitc::BINOP_UDIV:
+ return IsFP ? -1 : Instruction::UDiv;
case bitc::BINOP_SDIV:
- return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
- case bitc::BINOP_UREM: return Instruction::URem;
+ return IsFP ? Instruction::FDiv : Instruction::SDiv;
+ case bitc::BINOP_UREM:
+ return IsFP ? -1 : Instruction::URem;
case bitc::BINOP_SREM:
- return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
- case bitc::BINOP_SHL: return Instruction::Shl;
- case bitc::BINOP_LSHR: return Instruction::LShr;
- case bitc::BINOP_ASHR: return Instruction::AShr;
- case bitc::BINOP_AND: return Instruction::And;
- case bitc::BINOP_OR: return Instruction::Or;
- case bitc::BINOP_XOR: return Instruction::Xor;
+ return IsFP ? Instruction::FRem : Instruction::SRem;
+ case bitc::BINOP_SHL:
+ return IsFP ? -1 : Instruction::Shl;
+ case bitc::BINOP_LSHR:
+ return IsFP ? -1 : Instruction::LShr;
+ case bitc::BINOP_ASHR:
+ return IsFP ? -1 : Instruction::AShr;
+ case bitc::BINOP_AND:
+ return IsFP ? -1 : Instruction::And;
+ case bitc::BINOP_OR:
+ return IsFP ? -1 : Instruction::Or;
+ case bitc::BINOP_XOR:
+ return IsFP ? -1 : Instruction::Xor;
}
}
@@ -332,7 +718,7 @@ namespace {
/// @brief A class for maintaining the slot number definition
/// as a placeholder for the actual definition for forward constants defs.
class ConstantPlaceHolder : public ConstantExpr {
- void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION;
+ void operator=(const ConstantPlaceHolder &) = delete;
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
@@ -399,7 +785,8 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
resize(Idx + 1);
if (Value *V = ValuePtrs[Idx]) {
- assert(Ty == V->getType() && "Type mismatch in constant table!");
+ if (Ty != V->getType())
+ report_fatal_error("Type mismatch in constant table!");
return cast<Constant>(V);
}
@@ -410,11 +797,17 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
}
Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
+ // Bail out for a clearly invalid value. This would make us call resize(0)
+ if (Idx == UINT_MAX)
+ return nullptr;
+
if (Idx >= size())
resize(Idx + 1);
if (Value *V = ValuePtrs[Idx]) {
- assert((!Ty || Ty == V->getType()) && "Type mismatch in value table!");
+ // If the types don't match, it's invalid.
+ if (Ty && Ty != V->getType())
+ return nullptr;
return V;
}
@@ -525,9 +918,8 @@ void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
}
// If there was a forward reference to this value, replace it.
- MDNodeFwdDecl *PrevMD = cast<MDNodeFwdDecl>(OldMD.get());
+ TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
PrevMD->replaceAllUsesWith(MD);
- MDNode::deleteTemporary(PrevMD);
--NumFwdRefs;
}
@@ -549,7 +941,7 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
++NumFwdRefs;
// Create and return a placeholder, which will later be RAUW'd.
- Metadata *MD = MDNode::getTemporary(Context, None);
+ Metadata *MD = MDNode::getTemporary(Context, None).release();
MDValuePtrs[Idx].reset(MD);
return MD;
}
@@ -566,9 +958,12 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
// Resolve any cycles.
for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
auto &MD = MDValuePtrs[I];
- assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
- if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))
- N->resolveCycles();
+ auto *N = dyn_cast_or_null<MDNode>(MD);
+ if (!N)
+ continue;
+
+ assert(!N->isTemporary() && "Unexpected forward reference");
+ N->resolveCycles();
}
// Make sure we return early again until there's another forward ref.
@@ -701,6 +1096,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
return Attribute::InAlloca;
case bitc::ATTR_KIND_COLD:
return Attribute::Cold;
+ case bitc::ATTR_KIND_CONVERGENT:
+ return Attribute::Convergent;
case bitc::ATTR_KIND_INLINE_HINT:
return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
@@ -731,6 +1128,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
return Attribute::NonNull;
case bitc::ATTR_KIND_DEREFERENCEABLE:
return Attribute::Dereferenceable;
+ case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL:
+ return Attribute::DereferenceableOrNull;
case bitc::ATTR_KIND_NO_RED_ZONE:
return Attribute::NoRedZone;
case bitc::ATTR_KIND_NO_RETURN:
@@ -774,6 +1173,16 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
}
}
+std::error_code BitcodeReader::parseAlignmentValue(uint64_t Exponent,
+ unsigned &Alignment) {
+ // Note: Alignment in bitcode files is incremented by 1, so that zero
+ // can be used for default alignment.
+ if (Exponent > Value::MaxAlignmentExponent + 1)
+ return Error("Invalid alignment value");
+ Alignment = (1 << static_cast<unsigned>(Exponent)) >> 1;
+ return std::error_code();
+}
+
std::error_code BitcodeReader::ParseAttrKind(uint64_t Code,
Attribute::AttrKind *Kind) {
*Kind = GetAttrFromCode(Code);
@@ -837,6 +1246,8 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() {
B.addStackAlignmentAttr(Record[++i]);
else if (Kind == Attribute::Dereferenceable)
B.addDereferenceableAttr(Record[++i]);
+ else if (Kind == Attribute::DereferenceableOrNull)
+ B.addDereferenceableOrNullAttr(Record[++i]);
} else { // String attribute
assert((Record[i] == 3 || Record[i] == 4) &&
"Invalid attribute group entry");
@@ -943,12 +1354,17 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_X86_MMX: // X86_MMX
ResultTy = Type::getX86_MMXTy(Context);
break;
- case bitc::TYPE_CODE_INTEGER: // INTEGER: [width]
+ case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width]
if (Record.size() < 1)
return Error("Invalid record");
- ResultTy = IntegerType::get(Context, Record[0]);
+ uint64_t NumBits = Record[0];
+ if (NumBits < IntegerType::MIN_INT_BITS ||
+ NumBits > IntegerType::MAX_INT_BITS)
+ return Error("Bitwidth for integer type out of range");
+ ResultTy = IntegerType::get(Context, NumBits);
break;
+ }
case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
// [pointee type, address space]
if (Record.size() < 1)
@@ -957,7 +1373,8 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
if (Record.size() == 2)
AddressSpace = Record[1];
ResultTy = getTypeByID(Record[0]);
- if (!ResultTy)
+ if (!ResultTy ||
+ !PointerType::isValidElementType(ResultTy))
return Error("Invalid type");
ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
@@ -988,8 +1405,11 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
return Error("Invalid record");
SmallVector<Type*, 8> ArgTys;
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
- if (Type *T = getTypeByID(Record[i]))
+ if (Type *T = getTypeByID(Record[i])) {
+ if (!FunctionType::isValidArgumentType(T))
+ return Error("Invalid function argument type");
ArgTys.push_back(T);
+ }
else
break;
}
@@ -1071,25 +1491,27 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid record");
- if ((ResultTy = getTypeByID(Record[1])))
- ResultTy = ArrayType::get(ResultTy, Record[0]);
- else
+ ResultTy = getTypeByID(Record[1]);
+ if (!ResultTy || !ArrayType::isValidElementType(ResultTy))
return Error("Invalid type");
+ ResultTy = ArrayType::get(ResultTy, Record[0]);
break;
case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid record");
- if ((ResultTy = getTypeByID(Record[1])))
- ResultTy = VectorType::get(ResultTy, Record[0]);
- else
+ ResultTy = getTypeByID(Record[1]);
+ if (!ResultTy || !StructType::isValidElementType(ResultTy))
return Error("Invalid type");
+ ResultTy = VectorType::get(ResultTy, Record[0]);
break;
}
if (NumRecords >= TypeList.size())
return Error("Invalid TYPE table");
+ if (TypeList[NumRecords])
+ return Error(
+ "Invalid TYPE table: Only named structs can be forward referenced");
assert(ResultTy && "Didn't read a type?");
- assert(!TypeList[NumRecords] && "Already read type?");
TypeList[NumRecords++] = ResultTy;
}
}
@@ -1100,6 +1522,8 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
SmallVector<uint64_t, 64> Record;
+ Triple TT(TheModule->getTargetTriple());
+
// Read all the records for this value table.
SmallString<128> ValueName;
while (1) {
@@ -1130,6 +1554,14 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
Value *V = ValueList[ValueID];
V->setName(StringRef(ValueName.data(), ValueName.size()));
+ if (auto *GO = dyn_cast<GlobalObject>(V)) {
+ if (GO->getComdat() == reinterpret_cast<Comdat *>(1)) {
+ if (TT.isOSBinFormatMachO())
+ GO->setComdat(nullptr);
+ else
+ GO->setComdat(TheModule->getOrInsertComdat(V->getName()));
+ }
+ }
ValueName.clear();
break;
}
@@ -1148,7 +1580,10 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
}
}
+static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
+
std::error_code BitcodeReader::ParseMetadata() {
+ IsMetadataMaterialized = true;
unsigned NextMDValueNo = MDValueList.size();
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
@@ -1156,6 +1591,22 @@ std::error_code BitcodeReader::ParseMetadata() {
SmallVector<uint64_t, 64> Record;
+ auto getMD =
+ [&](unsigned ID) -> Metadata *{ return MDValueList.getValueFwdRef(ID); };
+ auto getMDOrNull = [&](unsigned ID) -> Metadata *{
+ if (ID)
+ return getMD(ID - 1);
+ return nullptr;
+ };
+ auto getMDString = [&](unsigned ID) -> MDString *{
+ // This requires that the ID is not really a forward reference. In
+ // particular, the MDString must already have been resolved.
+ return cast_or_null<MDString>(getMDOrNull(ID));
+ };
+
+#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \
+ (DISTINCT ? CLASS::getDistinct ARGS : CLASS::get ARGS)
+
// Read all the records.
while (1) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
@@ -1283,16 +1734,270 @@ std::error_code BitcodeReader::ParseMetadata() {
if (Record.size() != 5)
return Error("Invalid record");
- auto get = Record[0] ? MDLocation::getDistinct : MDLocation::get;
unsigned Line = Record[1];
unsigned Column = Record[2];
MDNode *Scope = cast<MDNode>(MDValueList.getValueFwdRef(Record[3]));
Metadata *InlinedAt =
Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr;
- MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt),
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DILocation, Record[0],
+ (Context, Line, Column, Scope, InlinedAt)),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_GENERIC_DEBUG: {
+ if (Record.size() < 4)
+ return Error("Invalid record");
+
+ unsigned Tag = Record[1];
+ unsigned Version = Record[2];
+
+ if (Tag >= 1u << 16 || Version != 0)
+ return Error("Invalid record");
+
+ auto *Header = getMDString(Record[3]);
+ SmallVector<Metadata *, 8> DwarfOps;
+ for (unsigned I = 4, E = Record.size(); I != E; ++I)
+ DwarfOps.push_back(Record[I] ? MDValueList.getValueFwdRef(Record[I] - 1)
+ : nullptr);
+ MDValueList.AssignValue(GET_OR_DISTINCT(GenericDINode, Record[0],
+ (Context, Tag, Header, DwarfOps)),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_SUBRANGE: {
+ if (Record.size() != 3)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DISubrange, Record[0],
+ (Context, Record[1], unrotateSign(Record[2]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_ENUMERATOR: {
+ if (Record.size() != 3)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(GET_OR_DISTINCT(DIEnumerator, Record[0],
+ (Context, unrotateSign(Record[1]),
+ getMDString(Record[2]))),
NextMDValueNo++);
break;
}
+ case bitc::METADATA_BASIC_TYPE: {
+ if (Record.size() != 6)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIBasicType, Record[0],
+ (Context, Record[1], getMDString(Record[2]),
+ Record[3], Record[4], Record[5])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_DERIVED_TYPE: {
+ if (Record.size() != 12)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIDerivedType, Record[0],
+ (Context, Record[1], getMDString(Record[2]),
+ getMDOrNull(Record[3]), Record[4],
+ getMDOrNull(Record[5]), getMDOrNull(Record[6]),
+ Record[7], Record[8], Record[9], Record[10],
+ getMDOrNull(Record[11]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_COMPOSITE_TYPE: {
+ if (Record.size() != 16)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DICompositeType, Record[0],
+ (Context, Record[1], getMDString(Record[2]),
+ getMDOrNull(Record[3]), Record[4],
+ getMDOrNull(Record[5]), getMDOrNull(Record[6]),
+ Record[7], Record[8], Record[9], Record[10],
+ getMDOrNull(Record[11]), Record[12],
+ getMDOrNull(Record[13]), getMDOrNull(Record[14]),
+ getMDString(Record[15]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_SUBROUTINE_TYPE: {
+ if (Record.size() != 3)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DISubroutineType, Record[0],
+ (Context, Record[1], getMDOrNull(Record[2]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_FILE: {
+ if (Record.size() != 3)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIFile, Record[0], (Context, getMDString(Record[1]),
+ getMDString(Record[2]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_COMPILE_UNIT: {
+ if (Record.size() < 14 || Record.size() > 15)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DICompileUnit, Record[0],
+ (Context, Record[1], getMDOrNull(Record[2]),
+ getMDString(Record[3]), Record[4],
+ getMDString(Record[5]), Record[6],
+ getMDString(Record[7]), Record[8],
+ getMDOrNull(Record[9]), getMDOrNull(Record[10]),
+ getMDOrNull(Record[11]), getMDOrNull(Record[12]),
+ getMDOrNull(Record[13]),
+ Record.size() == 14 ? 0 : Record[14])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_SUBPROGRAM: {
+ if (Record.size() != 19)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(
+ DISubprogram, Record[0],
+ (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
+ getMDOrNull(Record[6]), Record[7], Record[8], Record[9],
+ getMDOrNull(Record[10]), Record[11], Record[12], Record[13],
+ Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]),
+ getMDOrNull(Record[17]), getMDOrNull(Record[18]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_LEXICAL_BLOCK: {
+ if (Record.size() != 5)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DILexicalBlock, Record[0],
+ (Context, getMDOrNull(Record[1]),
+ getMDOrNull(Record[2]), Record[3], Record[4])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_LEXICAL_BLOCK_FILE: {
+ if (Record.size() != 4)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DILexicalBlockFile, Record[0],
+ (Context, getMDOrNull(Record[1]),
+ getMDOrNull(Record[2]), Record[3])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_NAMESPACE: {
+ if (Record.size() != 5)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DINamespace, Record[0],
+ (Context, getMDOrNull(Record[1]),
+ getMDOrNull(Record[2]), getMDString(Record[3]),
+ Record[4])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_TEMPLATE_TYPE: {
+ if (Record.size() != 3)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
+ Record[0],
+ (Context, getMDString(Record[1]),
+ getMDOrNull(Record[2]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_TEMPLATE_VALUE: {
+ if (Record.size() != 5)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DITemplateValueParameter, Record[0],
+ (Context, Record[1], getMDString(Record[2]),
+ getMDOrNull(Record[3]), getMDOrNull(Record[4]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_GLOBAL_VAR: {
+ if (Record.size() != 11)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIGlobalVariable, Record[0],
+ (Context, getMDOrNull(Record[1]),
+ getMDString(Record[2]), getMDString(Record[3]),
+ getMDOrNull(Record[4]), Record[5],
+ getMDOrNull(Record[6]), Record[7], Record[8],
+ getMDOrNull(Record[9]), getMDOrNull(Record[10]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_LOCAL_VAR: {
+ // 10th field is for the obseleted 'inlinedAt:' field.
+ if (Record.size() != 9 && Record.size() != 10)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DILocalVariable, Record[0],
+ (Context, Record[1], getMDOrNull(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]),
+ Record[5], getMDOrNull(Record[6]), Record[7],
+ Record[8])),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_EXPRESSION: {
+ if (Record.size() < 1)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIExpression, Record[0],
+ (Context, makeArrayRef(Record).slice(1))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_OBJC_PROPERTY: {
+ if (Record.size() != 8)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIObjCProperty, Record[0],
+ (Context, getMDString(Record[1]),
+ getMDOrNull(Record[2]), Record[3],
+ getMDString(Record[4]), getMDString(Record[5]),
+ Record[6], getMDOrNull(Record[7]))),
+ NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_IMPORTED_ENTITY: {
+ if (Record.size() != 6)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(DIImportedEntity, Record[0],
+ (Context, Record[1], getMDOrNull(Record[2]),
+ getMDOrNull(Record[3]), Record[4],
+ getMDString(Record[5]))),
+ NextMDValueNo++);
+ break;
+ }
case bitc::METADATA_STRING: {
std::string String(Record.begin(), Record.end());
llvm::UpgradeMDStringConstant(String);
@@ -1314,6 +2019,7 @@ std::error_code BitcodeReader::ParseMetadata() {
}
}
}
+#undef GET_OR_DISTINCT
}
/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
@@ -1635,19 +2341,29 @@ std::error_code BitcodeReader::ParseConstants() {
}
case bitc::CST_CODE_CE_INBOUNDS_GEP:
case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands]
- if (Record.size() & 1)
- return Error("Invalid record");
+ unsigned OpNum = 0;
+ Type *PointeeType = nullptr;
+ if (Record.size() % 2)
+ PointeeType = getTypeByID(Record[OpNum++]);
SmallVector<Constant*, 16> Elts;
- for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
- Type *ElTy = getTypeByID(Record[i]);
+ while (OpNum != Record.size()) {
+ Type *ElTy = getTypeByID(Record[OpNum++]);
if (!ElTy)
return Error("Invalid record");
- Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
+ Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy));
}
+
+ if (PointeeType &&
+ PointeeType !=
+ cast<SequentialType>(Elts[0]->getType()->getScalarType())
+ ->getElementType())
+ return Error("Explicit gep operator type does not match pointee type "
+ "of pointer operand");
+
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
- V = ConstantExpr::getGetElementPtr(Elts[0], Indices,
+ V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
BitCode ==
- bitc::CST_CODE_CE_INBOUNDS_GEP);
+ bitc::CST_CODE_CE_INBOUNDS_GEP);
break;
}
case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#]
@@ -1917,6 +2633,32 @@ std::error_code BitcodeReader::ParseUseLists() {
}
}
+/// When we see the block for metadata, remember where it is and then skip it.
+/// This lets us lazily deserialize the metadata.
+std::error_code BitcodeReader::rememberAndSkipMetadata() {
+ // Save the current stream state.
+ uint64_t CurBit = Stream.GetCurrentBitNo();
+ DeferredMetadataInfo.push_back(CurBit);
+
+ // Skip over the block for now.
+ if (Stream.SkipBlock())
+ return Error("Invalid record");
+ return std::error_code();
+}
+
+std::error_code BitcodeReader::materializeMetadata() {
+ for (uint64_t BitPos : DeferredMetadataInfo) {
+ // Move the bit stream to the saved position.
+ Stream.JumpToBit(BitPos);
+ if (std::error_code EC = ParseMetadata())
+ return EC;
+ }
+ DeferredMetadataInfo.clear();
+ return std::error_code();
+}
+
+void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; }
+
/// RememberAndSkipFunctionBody - When we see the block for a function body,
/// remember where it is and then skip it. This lets us lazily deserialize the
/// functions.
@@ -1967,7 +2709,8 @@ std::error_code BitcodeReader::GlobalCleanup() {
return std::error_code();
}
-std::error_code BitcodeReader::ParseModule(bool Resume) {
+std::error_code BitcodeReader::ParseModule(bool Resume,
+ bool ShouldLazyLoadMetadata) {
if (Resume)
Stream.JumpToBit(NextUnreadBit);
else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
@@ -2021,6 +2764,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
return EC;
break;
case bitc::METADATA_BLOCK_ID:
+ if (ShouldLazyLoadMetadata && !IsMetadataMaterialized) {
+ if (std::error_code EC = rememberAndSkipMetadata())
+ return EC;
+ break;
+ }
+ assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata");
if (std::error_code EC = ParseMetadata())
return EC;
break;
@@ -2139,21 +2888,31 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
}
// GLOBALVAR: [pointer type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
- // unnamed_addr, dllstorageclass]
+ // unnamed_addr, externally_initialized, dllstorageclass,
+ // comdat]
case bitc::MODULE_CODE_GLOBALVAR: {
if (Record.size() < 6)
return Error("Invalid record");
Type *Ty = getTypeByID(Record[0]);
if (!Ty)
return Error("Invalid record");
- if (!Ty->isPointerTy())
- return Error("Invalid type for value");
- unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
- Ty = cast<PointerType>(Ty)->getElementType();
+ bool isConstant = Record[1] & 1;
+ bool explicitType = Record[1] & 2;
+ unsigned AddressSpace;
+ if (explicitType) {
+ AddressSpace = Record[1] >> 2;
+ } else {
+ if (!Ty->isPointerTy())
+ return Error("Invalid type for value");
+ AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
+ Ty = cast<PointerType>(Ty)->getElementType();
+ }
- bool isConstant = Record[1];
- GlobalValue::LinkageTypes Linkage = getDecodedLinkage(Record[3]);
- unsigned Alignment = (1 << Record[4]) >> 1;
+ uint64_t RawLinkage = Record[3];
+ GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
+ unsigned Alignment;
+ if (std::error_code EC = parseAlignmentValue(Record[4], Alignment))
+ return EC;
std::string Section;
if (Record[5]) {
if (Record[5]-1 >= SectionTable.size())
@@ -2190,7 +2949,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (Record.size() > 10)
NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
else
- UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+ UpgradeDLLImportExportLinkage(NewGV, RawLinkage);
ValueList.push_back(NewGV);
@@ -2198,11 +2957,15 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (unsigned InitID = Record[2])
GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
- if (Record.size() > 11)
+ if (Record.size() > 11) {
if (unsigned ComdatID = Record[11]) {
- assert(ComdatID <= ComdatList.size());
+ if (ComdatID > ComdatList.size())
+ return Error("Invalid global variable comdat ID");
NewGV->setComdat(ComdatList[ComdatID - 1]);
}
+ } else if (hasImplicitComdat(RawLinkage)) {
+ NewGV->setComdat(reinterpret_cast<Comdat *>(1));
+ }
break;
}
// FUNCTION: [type, callingconv, isproto, linkage, paramattr,
@@ -2214,10 +2977,9 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
Type *Ty = getTypeByID(Record[0]);
if (!Ty)
return Error("Invalid record");
- if (!Ty->isPointerTy())
- return Error("Invalid type for value");
- FunctionType *FTy =
- dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
+ if (auto *PTy = dyn_cast<PointerType>(Ty))
+ Ty = PTy->getElementType();
+ auto *FTy = dyn_cast<FunctionType>(Ty);
if (!FTy)
return Error("Invalid type for value");
@@ -2226,10 +2988,14 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
bool isProto = Record[2];
- Func->setLinkage(getDecodedLinkage(Record[3]));
+ uint64_t RawLinkage = Record[3];
+ Func->setLinkage(getDecodedLinkage(RawLinkage));
Func->setAttributes(getAttributes(Record[4]));
- Func->setAlignment((1 << Record[5]) >> 1);
+ unsigned Alignment;
+ if (std::error_code EC = parseAlignmentValue(Record[5], Alignment))
+ return EC;
+ Func->setAlignment(Alignment);
if (Record[6]) {
if (Record[6]-1 >= SectionTable.size())
return Error("Invalid ID");
@@ -2240,7 +3006,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
// FIXME: Change to an error if non-default in 4.0.
Func->setVisibility(GetDecodedVisibility(Record[7]));
if (Record.size() > 8 && Record[8]) {
- if (Record[8]-1 > GCTable.size())
+ if (Record[8]-1 >= GCTable.size())
return Error("Invalid ID");
Func->setGC(GCTable[Record[8]-1].c_str());
}
@@ -2254,13 +3020,17 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (Record.size() > 11)
Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
else
- UpgradeDLLImportExportLinkage(Func, Record[3]);
+ UpgradeDLLImportExportLinkage(Func, RawLinkage);
- if (Record.size() > 12)
+ if (Record.size() > 12) {
if (unsigned ComdatID = Record[12]) {
- assert(ComdatID <= ComdatList.size());
+ if (ComdatID > ComdatList.size())
+ return Error("Invalid function comdat ID");
Func->setComdat(ComdatList[ComdatID - 1]);
}
+ } else if (hasImplicitComdat(RawLinkage)) {
+ Func->setComdat(reinterpret_cast<Comdat *>(1));
+ }
if (Record.size() > 13 && Record[13] != 0)
FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1));
@@ -2290,8 +3060,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
return Error("Invalid type for value");
auto *NewGA =
- GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
- getDecodedLinkage(Record[2]), "", TheModule);
+ GlobalAlias::create(PTy, getDecodedLinkage(Record[2]), "", TheModule);
// Old bitcode files didn't have visibility field.
// Local linkage must have default visibility.
if (Record.size() > 3 && !NewGA->hasLocalLinkage())
@@ -2321,7 +3090,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
}
}
-std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
+std::error_code BitcodeReader::ParseBitcodeInto(Module *M,
+ bool ShouldLazyLoadMetadata) {
TheModule = nullptr;
if (std::error_code EC = InitStream())
@@ -2339,8 +3109,12 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
// We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all.
while (1) {
- if (Stream.AtEndOfStream())
- return std::error_code();
+ if (Stream.AtEndOfStream()) {
+ if (TheModule)
+ return std::error_code();
+ // We didn't really read a proper Module.
+ return Error("Malformed IR file");
+ }
BitstreamEntry Entry =
Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
@@ -2362,7 +3136,7 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
if (TheModule)
return Error("Invalid multiple blocks");
TheModule = M;
- if (std::error_code EC = ParseModule(false))
+ if (std::error_code EC = ParseModule(false, ShouldLazyLoadMetadata))
return EC;
if (LazyStreamer)
return std::error_code();
@@ -2468,7 +3242,7 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
}
/// ParseMetadataAttachment - Parse metadata attachments.
-std::error_code BitcodeReader::ParseMetadataAttachment() {
+std::error_code BitcodeReader::ParseMetadataAttachment(Function &F) {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return Error("Invalid record");
@@ -2494,8 +3268,21 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
break;
case bitc::METADATA_ATTACHMENT: {
unsigned RecordLength = Record.size();
- if (Record.empty() || (RecordLength - 1) % 2 == 1)
+ if (Record.empty())
return Error("Invalid record");
+ if (RecordLength % 2 == 0) {
+ // A function attachment.
+ for (unsigned I = 0; I != RecordLength; I += 2) {
+ auto K = MDKindMap.find(Record[I]);
+ if (K == MDKindMap.end())
+ return Error("Invalid ID");
+ Metadata *MD = MDValueList.getValueFwdRef(Record[I + 1]);
+ F.setMetadata(K->second, cast<MDNode>(MD));
+ }
+ continue;
+ }
+
+ // An instruction attachment.
Instruction *Inst = InstructionList[Record[0]];
for (unsigned i = 1; i != RecordLength; i = i+2) {
unsigned Kind = Record[i];
@@ -2518,6 +3305,20 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
}
}
+static std::error_code TypeCheckLoadStoreInst(DiagnosticHandlerFunction DH,
+ Type *ValType, Type *PtrType) {
+ if (!isa<PointerType>(PtrType))
+ return Error(DH, "Load/Store operand is not a pointer type");
+ Type *ElemType = cast<PointerType>(PtrType)->getElementType();
+
+ if (ValType && ValType != ElemType)
+ return Error(DH, "Explicit load/store type does not match pointee type of "
+ "pointer operand");
+ if (!PointerType::isLoadableOrStorableType(ElemType))
+ return Error(DH, "Cannot load/store from pointer");
+ return std::error_code();
+}
+
/// ParseFunctionBody - Lazily parse the specified function body block.
std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
@@ -2572,7 +3373,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
return EC;
break;
case bitc::METADATA_ATTACHMENT_ID:
- if (std::error_code EC = ParseMetadataAttachment())
+ if (std::error_code EC = ParseMetadataAttachment(*F))
return EC;
break;
case bitc::METADATA_BLOCK_ID:
@@ -2731,13 +3532,35 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_INBOUNDS_GEP:
- case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
+ case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD:
+ case bitc::FUNC_CODE_INST_GEP_OLD:
+ case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands]
unsigned OpNum = 0;
+
+ Type *Ty;
+ bool InBounds;
+
+ if (BitCode == bitc::FUNC_CODE_INST_GEP) {
+ InBounds = Record[OpNum++];
+ Ty = getTypeByID(Record[OpNum++]);
+ } else {
+ InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+ Ty = nullptr;
+ }
+
Value *BasePtr;
if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
return Error("Invalid record");
+ if (!Ty)
+ Ty = cast<SequentialType>(BasePtr->getType()->getScalarType())
+ ->getElementType();
+ else if (Ty !=
+ cast<SequentialType>(BasePtr->getType()->getScalarType())
+ ->getElementType())
+ return Error(
+ "Explicit gep type does not match pointee type of pointer operand");
+
SmallVector<Value*, 16> GEPIdx;
while (OpNum != Record.size()) {
Value *Op;
@@ -2746,9 +3569,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
GEPIdx.push_back(Op);
}
- I = GetElementPtrInst::Create(BasePtr, GEPIdx);
+ I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
+
InstructionList.push_back(I);
- if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
+ if (InBounds)
cast<GetElementPtrInst>(I)->setIsInBounds(true);
break;
}
@@ -2760,13 +3584,31 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
return Error("Invalid record");
+ unsigned RecSize = Record.size();
+ if (OpNum == RecSize)
+ return Error("EXTRACTVAL: Invalid instruction with 0 indices");
+
SmallVector<unsigned, 4> EXTRACTVALIdx;
- for (unsigned RecSize = Record.size();
- OpNum != RecSize; ++OpNum) {
+ Type *CurTy = Agg->getType();
+ for (; OpNum != RecSize; ++OpNum) {
+ bool IsArray = CurTy->isArrayTy();
+ bool IsStruct = CurTy->isStructTy();
uint64_t Index = Record[OpNum];
+
+ if (!IsStruct && !IsArray)
+ return Error("EXTRACTVAL: Invalid type");
if ((unsigned)Index != Index)
return Error("Invalid value");
+ if (IsStruct && Index >= CurTy->subtypes().size())
+ return Error("EXTRACTVAL: Invalid struct index");
+ if (IsArray && Index >= CurTy->getArrayNumElements())
+ return Error("EXTRACTVAL: Invalid array index");
EXTRACTVALIdx.push_back((unsigned)Index);
+
+ if (IsStruct)
+ CurTy = CurTy->subtypes()[Index];
+ else
+ CurTy = CurTy->subtypes()[0];
}
I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
@@ -2784,15 +3626,36 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
return Error("Invalid record");
+ unsigned RecSize = Record.size();
+ if (OpNum == RecSize)
+ return Error("INSERTVAL: Invalid instruction with 0 indices");
+
SmallVector<unsigned, 4> INSERTVALIdx;
- for (unsigned RecSize = Record.size();
- OpNum != RecSize; ++OpNum) {
+ Type *CurTy = Agg->getType();
+ for (; OpNum != RecSize; ++OpNum) {
+ bool IsArray = CurTy->isArrayTy();
+ bool IsStruct = CurTy->isStructTy();
uint64_t Index = Record[OpNum];
+
+ if (!IsStruct && !IsArray)
+ return Error("INSERTVAL: Invalid type");
if ((unsigned)Index != Index)
return Error("Invalid value");
+ if (IsStruct && Index >= CurTy->subtypes().size())
+ return Error("INSERTVAL: Invalid struct index");
+ if (IsArray && Index >= CurTy->getArrayNumElements())
+ return Error("INSERTVAL: Invalid array index");
+
INSERTVALIdx.push_back((unsigned)Index);
+ if (IsStruct)
+ CurTy = CurTy->subtypes()[Index];
+ else
+ CurTy = CurTy->subtypes()[0];
}
+ if (CurTy != Val->getType())
+ return Error("Inserted value type doesn't match aggregate type");
+
I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
InstructionList.push_back(I);
break;
@@ -2846,6 +3709,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
getValueTypePair(Record, OpNum, NextValueNo, Idx))
return Error("Invalid record");
+ if (!Vec->getType()->isVectorTy())
+ return Error("Invalid type for value");
I = ExtractElementInst::Create(Vec, Idx);
InstructionList.push_back(I);
break;
@@ -2854,8 +3719,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval]
unsigned OpNum = 0;
Value *Vec, *Elt, *Idx;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
- popValue(Record, OpNum, NextValueNo,
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec))
+ return Error("Invalid record");
+ if (!Vec->getType()->isVectorTy())
+ return Error("Invalid type for value");
+ if (popValue(Record, OpNum, NextValueNo,
cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
getValueTypePair(Record, OpNum, NextValueNo, Idx))
return Error("Invalid record");
@@ -2873,6 +3741,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
return Error("Invalid record");
+ if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy())
+ return Error("Invalid type for value");
I = new ShuffleVectorInst(Vec1, Vec2, Mask);
InstructionList.push_back(I);
break;
@@ -3056,24 +3926,33 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
if (Record.size() < 4)
return Error("Invalid record");
- AttributeSet PAL = getAttributes(Record[0]);
- unsigned CCInfo = Record[1];
- BasicBlock *NormalBB = getBasicBlock(Record[2]);
- BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+ unsigned OpNum = 0;
+ AttributeSet PAL = getAttributes(Record[OpNum++]);
+ unsigned CCInfo = Record[OpNum++];
+ BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]);
+ BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]);
+
+ FunctionType *FTy = nullptr;
+ if (CCInfo >> 13 & 1 &&
+ !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
+ return Error("Explicit invoke type is not a function type");
- unsigned OpNum = 4;
Value *Callee;
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return Error("Invalid record");
PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
- FunctionType *FTy = !CalleeTy ? nullptr :
- dyn_cast<FunctionType>(CalleeTy->getElementType());
-
- // Check that the right number of fixed parameters are here.
- if (!FTy || !NormalBB || !UnwindBB ||
- Record.size() < OpNum+FTy->getNumParams())
- return Error("Invalid record");
+ if (!CalleeTy)
+ return Error("Callee is not a pointer");
+ if (!FTy) {
+ FTy = dyn_cast<FunctionType>(CalleeTy->getElementType());
+ if (!FTy)
+ return Error("Callee is not of pointer to function type");
+ } else if (CalleeTy->getElementType() != FTy)
+ return Error("Explicit invoke type does not match pointee type of "
+ "callee operand");
+ if (Record.size() < FTy->getNumParams() + OpNum)
+ return Error("Insufficient operands to call");
SmallVector<Value*, 16> Ops;
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
@@ -3098,8 +3977,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops);
InstructionList.push_back(I);
- cast<InvokeInst>(I)->setCallingConv(
- static_cast<CallingConv::ID>(CCInfo));
+ cast<InvokeInst>(I)
+ ->setCallingConv(static_cast<CallingConv::ID>(~(1U << 13) & CCInfo));
cast<InvokeInst>(I)->setAttributes(PAL);
break;
}
@@ -3187,16 +4066,28 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
if (Record.size() != 4)
return Error("Invalid record");
- PointerType *Ty =
- dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+ uint64_t AlignRecord = Record[3];
+ const uint64_t InAllocaMask = uint64_t(1) << 5;
+ const uint64_t ExplicitTypeMask = uint64_t(1) << 6;
+ const uint64_t FlagMask = InAllocaMask | ExplicitTypeMask;
+ bool InAlloca = AlignRecord & InAllocaMask;
+ Type *Ty = getTypeByID(Record[0]);
+ if ((AlignRecord & ExplicitTypeMask) == 0) {
+ auto *PTy = dyn_cast_or_null<PointerType>(Ty);
+ if (!PTy)
+ return Error("Old-style alloca with a non-pointer type");
+ Ty = PTy->getElementType();
+ }
Type *OpTy = getTypeByID(Record[1]);
Value *Size = getFnValueByID(Record[2], OpTy);
- unsigned AlignRecord = Record[3];
- bool InAlloca = AlignRecord & (1 << 5);
- unsigned Align = AlignRecord & ((1 << 5) - 1);
+ unsigned Align;
+ if (std::error_code EC =
+ parseAlignmentValue(AlignRecord & ~FlagMask, Align)) {
+ return EC;
+ }
if (!Ty || !Size)
return Error("Invalid record");
- AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+ AllocaInst *AI = new AllocaInst(Ty, Size, Align);
AI->setUsedWithInAlloca(InAlloca);
I = AI;
InstructionList.push_back(I);
@@ -3206,10 +4097,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
- OpNum+2 != Record.size())
+ (OpNum + 2 != Record.size() && OpNum + 3 != Record.size()))
return Error("Invalid record");
- I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ Type *Ty = nullptr;
+ if (OpNum + 3 == Record.size())
+ Ty = getTypeByID(Record[OpNum++]);
+ if (std::error_code EC =
+ TypeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType()))
+ return EC;
+ if (!Ty)
+ Ty = cast<PointerType>(Op->getType())->getElementType();
+
+ unsigned Align;
+ if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align))
+ return EC;
+ I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align);
+
InstructionList.push_back(I);
break;
}
@@ -3218,9 +4122,18 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
- OpNum+4 != Record.size())
+ (OpNum + 4 != Record.size() && OpNum + 5 != Record.size()))
return Error("Invalid record");
+ Type *Ty = nullptr;
+ if (OpNum + 5 == Record.size())
+ Ty = getTypeByID(Record[OpNum++]);
+ if (std::error_code EC =
+ TypeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType()))
+ return EC;
+ if (!Ty)
+ Ty = cast<PointerType>(Op->getType())->getElementType();
+
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
if (Ordering == NotAtomic || Ordering == Release ||
Ordering == AcquireRelease)
@@ -3229,34 +4142,54 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
return Error("Invalid record");
SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
- I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1,
- Ordering, SynchScope);
+ unsigned Align;
+ if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align))
+ return EC;
+ I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope);
+
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_STORE: { // STORE2:[ptrty, ptr, val, align, vol]
+ case bitc::FUNC_CODE_INST_STORE:
+ case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol]
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
- OpNum+2 != Record.size())
+ (BitCode == bitc::FUNC_CODE_INST_STORE
+ ? getValueTypePair(Record, OpNum, NextValueNo, Val)
+ : popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Val)) ||
+ OpNum + 2 != Record.size())
return Error("Invalid record");
- I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ if (std::error_code EC = TypeCheckLoadStoreInst(
+ DiagnosticHandler, Val->getType(), Ptr->getType()))
+ return EC;
+ unsigned Align;
+ if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align))
+ return EC;
+ I = new StoreInst(Val, Ptr, Record[OpNum+1], Align);
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_STOREATOMIC: {
+ case bitc::FUNC_CODE_INST_STOREATOMIC:
+ case bitc::FUNC_CODE_INST_STOREATOMIC_OLD: {
// STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope]
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
- OpNum+4 != Record.size())
+ (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC
+ ? getValueTypePair(Record, OpNum, NextValueNo, Val)
+ : popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Val)) ||
+ OpNum + 4 != Record.size())
return Error("Invalid record");
+ if (std::error_code EC = TypeCheckLoadStoreInst(
+ DiagnosticHandler, Val->getType(), Ptr->getType()))
+ return EC;
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
if (Ordering == NotAtomic || Ordering == Acquire ||
Ordering == AcquireRelease)
@@ -3265,28 +4198,36 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (Ordering != NotAtomic && Record[OpNum] == 0)
return Error("Invalid record");
- I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1,
- Ordering, SynchScope);
+ unsigned Align;
+ if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align))
+ return EC;
+ I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SynchScope);
InstructionList.push_back(I);
break;
}
+ case bitc::FUNC_CODE_INST_CMPXCHG_OLD:
case bitc::FUNC_CODE_INST_CMPXCHG: {
// CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, synchscope,
// failureordering?, isweak?]
unsigned OpNum = 0;
Value *Ptr, *Cmp, *New;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(), Cmp) ||
- popValue(Record, OpNum, NextValueNo,
- cast<PointerType>(Ptr->getType())->getElementType(), New) ||
- (Record.size() < OpNum + 3 || Record.size() > OpNum + 5))
+ (BitCode == bitc::FUNC_CODE_INST_CMPXCHG
+ ? getValueTypePair(Record, OpNum, NextValueNo, Cmp)
+ : popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getElementType(),
+ Cmp)) ||
+ popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) ||
+ Record.size() < OpNum + 3 || Record.size() > OpNum + 5)
return Error("Invalid record");
AtomicOrdering SuccessOrdering = GetDecodedOrdering(Record[OpNum+1]);
if (SuccessOrdering == NotAtomic || SuccessOrdering == Unordered)
return Error("Invalid record");
SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]);
+ if (std::error_code EC = TypeCheckLoadStoreInst(
+ DiagnosticHandler, Cmp->getType(), Ptr->getType()))
+ return EC;
AtomicOrdering FailureOrdering;
if (Record.size() < 7)
FailureOrdering =
@@ -3350,19 +4291,31 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (Record.size() < 3)
return Error("Invalid record");
- AttributeSet PAL = getAttributes(Record[0]);
- unsigned CCInfo = Record[1];
+ unsigned OpNum = 0;
+ AttributeSet PAL = getAttributes(Record[OpNum++]);
+ unsigned CCInfo = Record[OpNum++];
+
+ FunctionType *FTy = nullptr;
+ if (CCInfo >> 15 & 1 &&
+ !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
+ return Error("Explicit call type is not a function type");
- unsigned OpNum = 2;
Value *Callee;
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return Error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
- FunctionType *FTy = nullptr;
- if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
- if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
- return Error("Invalid record");
+ if (!OpTy)
+ return Error("Callee is not a pointer type");
+ if (!FTy) {
+ FTy = dyn_cast<FunctionType>(OpTy->getElementType());
+ if (!FTy)
+ return Error("Callee is not of pointer to function type");
+ } else if (OpTy->getElementType() != FTy)
+ return Error("Explicit call type does not match pointee type of "
+ "callee operand");
+ if (Record.size() < FTy->getNumParams() + OpNum)
+ return Error("Insufficient operands to call");
SmallVector<Value*, 16> Args;
// Read the fixed params.
@@ -3389,7 +4342,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
}
- I = CallInst::Create(Callee, Args);
+ I = CallInst::Create(FTy, Callee, Args);
InstructionList.push_back(I);
cast<CallInst>(I)->setCallingConv(
static_cast<CallingConv::ID>((~(1U << 14) & CCInfo) >> 1));
@@ -3483,6 +4436,9 @@ std::error_code BitcodeReader::FindFunctionInStream(
void BitcodeReader::releaseBuffer() { Buffer.release(); }
std::error_code BitcodeReader::materialize(GlobalValue *GV) {
+ if (std::error_code EC = materializeMetadata())
+ return EC;
+
Function *F = dyn_cast<Function>(GV);
// If it's not a function or is already material, ignore the request.
if (!F || !F->isMaterializable())
@@ -3503,6 +4459,9 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) {
return EC;
F->setIsMaterializable(false);
+ if (StripDebugInfo)
+ stripDebugInfo(*F);
+
// Upgrade any old intrinsic calls in the function.
for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
E = UpgradedIntrinsics.end(); I != E; ++I) {
@@ -3533,7 +4492,7 @@ bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
return DeferredFunctionInfo.count(const_cast<Function*>(F));
}
-void BitcodeReader::Dematerialize(GlobalValue *GV) {
+void BitcodeReader::dematerialize(GlobalValue *GV) {
Function *F = dyn_cast<Function>(GV);
// If this function isn't dematerializable, this is a noop.
if (!F || !isDematerializable(F))
@@ -3546,10 +4505,13 @@ void BitcodeReader::Dematerialize(GlobalValue *GV) {
F->setIsMaterializable(true);
}
-std::error_code BitcodeReader::MaterializeModule(Module *M) {
+std::error_code BitcodeReader::materializeModule(Module *M) {
assert(M == TheModule &&
"Can only Materialize the Module this BitcodeReader is attached to.");
+ if (std::error_code EC = materializeMetadata())
+ return EC;
+
// Promise to materialize all forward references.
WillMaterializeAllForwardRefs = true;
@@ -3690,7 +4652,8 @@ const std::error_category &llvm::BitcodeErrorCategory() {
static ErrorOr<Module *>
getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context, bool WillMaterializeAll,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata = false) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R =
new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
@@ -3702,7 +4665,8 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
return EC;
};
- if (std::error_code EC = R->ParseBitcodeInto(M))
+ // Delay parsing Metadata if ShouldLazyLoadMetadata is true.
+ if (std::error_code EC = R->ParseBitcodeInto(M, ShouldLazyLoadMetadata))
return cleanupOnError(EC);
if (!WillMaterializeAll)
@@ -3717,9 +4681,10 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
ErrorOr<Module *>
llvm::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata) {
return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
- DiagnosticHandler);
+ DiagnosticHandler, ShouldLazyLoadMetadata);
}
ErrorOr<std::unique_ptr<Module>>
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
deleted file mode 100644
index 5090be48450e..000000000000
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ /dev/null
@@ -1,365 +0,0 @@
-//===- BitcodeReader.h - Internal BitcodeReader impl ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header defines the BitcodeReader class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_BITCODE_READER_BITCODEREADER_H
-#define LLVM_LIB_BITCODE_READER_BITCODEREADER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Bitcode/LLVMBitCodes.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/GVMaterializer.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/OperandTraits.h"
-#include "llvm/IR/TrackingMDRef.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/ValueHandle.h"
-#include <deque>
-#include <system_error>
-#include <vector>
-
-namespace llvm {
- class Comdat;
- class MemoryBuffer;
- class LLVMContext;
-
-//===----------------------------------------------------------------------===//
-// BitcodeReaderValueList Class
-//===----------------------------------------------------------------------===//
-
-class BitcodeReaderValueList {
- std::vector<WeakVH> ValuePtrs;
-
- /// ResolveConstants - As we resolve forward-referenced constants, we add
- /// information about them to this vector. This allows us to resolve them in
- /// bulk instead of resolving each reference at a time. See the code in
- /// ResolveConstantForwardRefs for more information about this.
- ///
- /// The key of this vector is the placeholder constant, the value is the slot
- /// number that holds the resolved value.
- typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
- ResolveConstantsTy ResolveConstants;
- LLVMContext &Context;
-public:
- BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
- ~BitcodeReaderValueList() {
- assert(ResolveConstants.empty() && "Constants not resolved?");
- }
-
- // vector compatibility methods
- unsigned size() const { return ValuePtrs.size(); }
- void resize(unsigned N) { ValuePtrs.resize(N); }
- void push_back(Value *V) {
- ValuePtrs.push_back(V);
- }
-
- void clear() {
- assert(ResolveConstants.empty() && "Constants not resolved?");
- ValuePtrs.clear();
- }
-
- Value *operator[](unsigned i) const {
- assert(i < ValuePtrs.size());
- return ValuePtrs[i];
- }
-
- Value *back() const { return ValuePtrs.back(); }
- void pop_back() { ValuePtrs.pop_back(); }
- bool empty() const { return ValuePtrs.empty(); }
- void shrinkTo(unsigned N) {
- assert(N <= size() && "Invalid shrinkTo request!");
- ValuePtrs.resize(N);
- }
-
- Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
- Value *getValueFwdRef(unsigned Idx, Type *Ty);
-
- void AssignValue(Value *V, unsigned Idx);
-
- /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
- /// resolves any forward references.
- void ResolveConstantForwardRefs();
-};
-
-
-//===----------------------------------------------------------------------===//
-// BitcodeReaderMDValueList Class
-//===----------------------------------------------------------------------===//
-
-class BitcodeReaderMDValueList {
- unsigned NumFwdRefs;
- bool AnyFwdRefs;
- unsigned MinFwdRef;
- unsigned MaxFwdRef;
- std::vector<TrackingMDRef> MDValuePtrs;
-
- LLVMContext &Context;
-public:
- BitcodeReaderMDValueList(LLVMContext &C)
- : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
-
- // vector compatibility methods
- unsigned size() const { return MDValuePtrs.size(); }
- void resize(unsigned N) { MDValuePtrs.resize(N); }
- void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); }
- void clear() { MDValuePtrs.clear(); }
- Metadata *back() const { return MDValuePtrs.back(); }
- void pop_back() { MDValuePtrs.pop_back(); }
- bool empty() const { return MDValuePtrs.empty(); }
-
- Metadata *operator[](unsigned i) const {
- assert(i < MDValuePtrs.size());
- return MDValuePtrs[i];
- }
-
- void shrinkTo(unsigned N) {
- assert(N <= size() && "Invalid shrinkTo request!");
- MDValuePtrs.resize(N);
- }
-
- Metadata *getValueFwdRef(unsigned Idx);
- void AssignValue(Metadata *MD, unsigned Idx);
- void tryToResolveCycles();
-};
-
-class BitcodeReader : public GVMaterializer {
- LLVMContext &Context;
- DiagnosticHandlerFunction DiagnosticHandler;
- Module *TheModule;
- std::unique_ptr<MemoryBuffer> Buffer;
- std::unique_ptr<BitstreamReader> StreamFile;
- BitstreamCursor Stream;
- DataStreamer *LazyStreamer;
- uint64_t NextUnreadBit;
- bool SeenValueSymbolTable;
-
- std::vector<Type*> TypeList;
- BitcodeReaderValueList ValueList;
- BitcodeReaderMDValueList MDValueList;
- std::vector<Comdat *> ComdatList;
- SmallVector<Instruction *, 64> InstructionList;
-
- std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
- std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
- std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
- std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
-
- SmallVector<Instruction*, 64> InstsWithTBAATag;
-
- /// MAttributes - The set of attributes by index. Index zero in the
- /// file is for null, and is thus not represented here. As such all indices
- /// are off by one.
- std::vector<AttributeSet> MAttributes;
-
- /// \brief The set of attribute groups.
- std::map<unsigned, AttributeSet> MAttributeGroups;
-
- /// FunctionBBs - While parsing a function body, this is a list of the basic
- /// blocks for the function.
- std::vector<BasicBlock*> FunctionBBs;
-
- // When reading the module header, this list is populated with functions that
- // have bodies later in the file.
- std::vector<Function*> FunctionsWithBodies;
-
- // When intrinsic functions are encountered which require upgrading they are
- // stored here with their replacement function.
- typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
- UpgradedIntrinsicMap UpgradedIntrinsics;
-
- // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
- DenseMap<unsigned, unsigned> MDKindMap;
-
- // Several operations happen after the module header has been read, but
- // before function bodies are processed. This keeps track of whether
- // we've done this yet.
- bool SeenFirstFunctionBody;
-
- /// DeferredFunctionInfo - When function bodies are initially scanned, this
- /// map contains info about where to find deferred function body in the
- /// stream.
- DenseMap<Function*, uint64_t> DeferredFunctionInfo;
-
- /// These are basic blocks forward-referenced by block addresses. They are
- /// inserted lazily into functions when they're loaded. The basic block ID is
- /// its index into the vector.
- DenseMap<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs;
- std::deque<Function *> BasicBlockFwdRefQueue;
-
- /// UseRelativeIDs - Indicates that we are using a new encoding for
- /// instruction operands where most operands in the current
- /// FUNCTION_BLOCK are encoded relative to the instruction number,
- /// for a more compact encoding. Some instruction operands are not
- /// relative to the instruction ID: basic block numbers, and types.
- /// Once the old style function blocks have been phased out, we would
- /// not need this flag.
- bool UseRelativeIDs;
-
- /// True if all functions will be materialized, negating the need to process
- /// (e.g.) blockaddress forward references.
- bool WillMaterializeAllForwardRefs;
-
- /// Functions that have block addresses taken. This is usually empty.
- SmallPtrSet<const Function *, 4> BlockAddressesTaken;
-
-public:
- std::error_code Error(BitcodeError E, const Twine &Message);
- std::error_code Error(BitcodeError E);
- std::error_code Error(const Twine &Message);
-
- explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
- DiagnosticHandlerFunction DiagnosticHandler);
- explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C,
- DiagnosticHandlerFunction DiagnosticHandler);
- ~BitcodeReader() { FreeState(); }
-
- std::error_code materializeForwardReferencedFunctions();
-
- void FreeState();
-
- void releaseBuffer();
-
- bool isDematerializable(const GlobalValue *GV) const override;
- std::error_code materialize(GlobalValue *GV) override;
- std::error_code MaterializeModule(Module *M) override;
- std::vector<StructType *> getIdentifiedStructTypes() const override;
- void Dematerialize(GlobalValue *GV) override;
-
- /// @brief Main interface to parsing a bitcode buffer.
- /// @returns true if an error occurred.
- std::error_code ParseBitcodeInto(Module *M);
-
- /// @brief Cheap mechanism to just extract module triple
- /// @returns true if an error occurred.
- ErrorOr<std::string> parseTriple();
-
- static uint64_t decodeSignRotatedValue(uint64_t V);
-
-private:
- std::vector<StructType *> IdentifiedStructTypes;
- StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
- StructType *createIdentifiedStructType(LLVMContext &Context);
-
- Type *getTypeByID(unsigned ID);
- Value *getFnValueByID(unsigned ID, Type *Ty) {
- if (Ty && Ty->isMetadataTy())
- return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
- return ValueList.getValueFwdRef(ID, Ty);
- }
- Metadata *getFnMetadataByID(unsigned ID) {
- return MDValueList.getValueFwdRef(ID);
- }
- BasicBlock *getBasicBlock(unsigned ID) const {
- if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID
- return FunctionBBs[ID];
- }
- AttributeSet getAttributes(unsigned i) const {
- if (i-1 < MAttributes.size())
- return MAttributes[i-1];
- return AttributeSet();
- }
-
- /// getValueTypePair - Read a value/type pair out of the specified record from
- /// slot 'Slot'. Increment Slot past the number of slots used in the record.
- /// Return true on failure.
- bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Value *&ResVal) {
- if (Slot == Record.size()) return true;
- unsigned ValNo = (unsigned)Record[Slot++];
- // Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
- ValNo = InstNum - ValNo;
- if (ValNo < InstNum) {
- // If this is not a forward reference, just return the value we already
- // have.
- ResVal = getFnValueByID(ValNo, nullptr);
- return ResVal == nullptr;
- } else if (Slot == Record.size()) {
- return true;
- }
-
- unsigned TypeNo = (unsigned)Record[Slot++];
- ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
- return ResVal == nullptr;
- }
-
- /// popValue - Read a value out of the specified record from slot 'Slot'.
- /// Increment Slot past the number of slots used by the value in the record.
- /// Return true if there is an error.
- bool popValue(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Type *Ty, Value *&ResVal) {
- if (getValue(Record, Slot, InstNum, Ty, ResVal))
- return true;
- // All values currently take a single record slot.
- ++Slot;
- return false;
- }
-
- /// getValue -- Like popValue, but does not increment the Slot number.
- bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty, Value *&ResVal) {
- ResVal = getValue(Record, Slot, InstNum, Ty);
- return ResVal == nullptr;
- }
-
- /// getValue -- Version of getValue that returns ResVal directly,
- /// or 0 if there is an error.
- Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty) {
- if (Slot == Record.size()) return nullptr;
- unsigned ValNo = (unsigned)Record[Slot];
- // Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
- ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty);
- }
-
- /// getValueSigned -- Like getValue, but decodes signed VBRs.
- Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty) {
- if (Slot == Record.size()) return nullptr;
- unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
- // Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
- ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty);
- }
-
- std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
- std::error_code ParseModule(bool Resume);
- std::error_code ParseAttributeBlock();
- std::error_code ParseAttributeGroupBlock();
- std::error_code ParseTypeTable();
- std::error_code ParseTypeTableBody();
-
- std::error_code ParseValueSymbolTable();
- std::error_code ParseConstants();
- std::error_code RememberAndSkipFunctionBody();
- std::error_code ParseFunctionBody(Function *F);
- std::error_code GlobalCleanup();
- std::error_code ResolveGlobalAndAliasInits();
- std::error_code ParseMetadata();
- std::error_code ParseMetadataAttachment();
- ErrorOr<std::string> parseModuleTriple();
- std::error_code ParseUseLists();
- std::error_code InitStream();
- std::error_code InitStreamFromBuffer();
- std::error_code InitLazyStream();
- std::error_code FindFunctionInStream(
- Function *F,
- DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator);
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp
index 5e3232e53135..a103fbdf4a93 100644
--- a/lib/Bitcode/Reader/BitstreamReader.cpp
+++ b/lib/Bitcode/Reader/BitstreamReader.cpp
@@ -39,15 +39,16 @@ bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
// Get the codesize of this block.
CurCodeSize = ReadVBR(bitc::CodeLenWidth);
+ // We can't read more than MaxChunkSize at a time
+ if (CurCodeSize > MaxChunkSize)
+ return true;
+
SkipToFourByteBoundary();
unsigned NumWords = Read(bitc::BlockSizeWidth);
if (NumWordsP) *NumWordsP = NumWords;
// Validate that this block is sane.
- if (CurCodeSize == 0 || AtEndOfStream())
- return true;
-
- return false;
+ return CurCodeSize == 0 || AtEndOfStream();
}
static uint64_t readAbbreviatedField(BitstreamCursor &Cursor,
@@ -60,8 +61,10 @@ static uint64_t readAbbreviatedField(BitstreamCursor &Cursor,
case BitCodeAbbrevOp::Blob:
llvm_unreachable("Should not reach here");
case BitCodeAbbrevOp::Fixed:
+ assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
return Cursor.Read((unsigned)Op.getEncodingData());
case BitCodeAbbrevOp::VBR:
+ assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
case BitCodeAbbrevOp::Char6:
return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6));
@@ -79,9 +82,11 @@ static void skipAbbreviatedField(BitstreamCursor &Cursor,
case BitCodeAbbrevOp::Blob:
llvm_unreachable("Should not reach here");
case BitCodeAbbrevOp::Fixed:
+ assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
Cursor.Read((unsigned)Op.getEncodingData());
break;
case BitCodeAbbrevOp::VBR:
+ assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
Cursor.ReadVBR64((unsigned)Op.getEncodingData());
break;
case BitCodeAbbrevOp::Char6:
@@ -170,8 +175,12 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
unsigned Code;
if (CodeOp.isLiteral())
Code = CodeOp.getLiteralValue();
- else
+ else {
+ if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
+ CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
+ report_fatal_error("Abbreviation starts with an Array or a Blob");
Code = readAbbreviatedField(*this, CodeOp);
+ }
for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
@@ -191,8 +200,15 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
unsigned NumElts = ReadVBR(6);
// Get the element encoding.
- assert(i+2 == e && "array op not second to last?");
+ if (i + 2 != e)
+ report_fatal_error("Array op not second to last");
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+ if (!EltEnc.isEncoding())
+ report_fatal_error(
+ "Array element type has to be an encoding of a type");
+ if (EltEnc.getEncoding() == BitCodeAbbrevOp::Array ||
+ EltEnc.getEncoding() == BitCodeAbbrevOp::Blob)
+ report_fatal_error("Array element type can't be an Array or a Blob");
// Read all the elements.
for (; NumElts; --NumElts)
@@ -241,7 +257,7 @@ void BitstreamCursor::ReadAbbrevRecord() {
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
unsigned NumOpInfo = ReadVBR(5);
for (unsigned i = 0; i != NumOpInfo; ++i) {
- bool IsLiteral = Read(1) ? true : false;
+ bool IsLiteral = Read(1);
if (IsLiteral) {
Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
continue;
@@ -249,7 +265,7 @@ void BitstreamCursor::ReadAbbrevRecord() {
BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
if (BitCodeAbbrevOp::hasEncodingData(E)) {
- unsigned Data = ReadVBR64(5);
+ uint64_t Data = ReadVBR64(5);
// As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
// and vbr(0) as a literal zero. This is decoded the same way, and avoids
@@ -260,10 +276,18 @@ void BitstreamCursor::ReadAbbrevRecord() {
continue;
}
+ if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
+ Data > MaxChunkSize)
+ report_fatal_error(
+ "Fixed or VBR abbrev record with size > MaxChunkData");
+
Abbv->Add(BitCodeAbbrevOp(E, Data));
} else
Abbv->Add(BitCodeAbbrevOp(E));
}
+
+ if (Abbv->getNumOperandInfos() == 0)
+ report_fatal_error("Abbrev record with no operands");
CurAbbrevs.push_back(Abbv);
}
diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt
index f614c9fd4a03..62954f26e208 100644
--- a/lib/Bitcode/Reader/CMakeLists.txt
+++ b/lib/Bitcode/Reader/CMakeLists.txt
@@ -2,6 +2,9 @@ add_llvm_library(LLVMBitReader
BitReader.cpp
BitcodeReader.cpp
BitstreamReader.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/Bitcode
)
add_dependencies(LLVMBitReader intrinsics_gen)
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index a96e866ed2c7..97caefb4c494 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -17,6 +17,7 @@
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
@@ -55,7 +56,8 @@ enum {
FUNCTION_INST_CAST_ABBREV,
FUNCTION_INST_RET_VOID_ABBREV,
FUNCTION_INST_RET_VAL_ABBREV,
- FUNCTION_INST_UNREACHABLE_ABBREV
+ FUNCTION_INST_UNREACHABLE_ABBREV,
+ FUNCTION_INST_GEP_ABBREV,
};
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
@@ -164,6 +166,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_BUILTIN;
case Attribute::ByVal:
return bitc::ATTR_KIND_BY_VAL;
+ case Attribute::Convergent:
+ return bitc::ATTR_KIND_CONVERGENT;
case Attribute::InAlloca:
return bitc::ATTR_KIND_IN_ALLOCA;
case Attribute::Cold:
@@ -198,6 +202,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NON_NULL;
case Attribute::Dereferenceable:
return bitc::ATTR_KIND_DEREFERENCEABLE;
+ case Attribute::DereferenceableOrNull:
+ return bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL;
case Attribute::NoRedZone:
return bitc::ATTR_KIND_NO_RED_ZONE;
case Attribute::NoReturn:
@@ -322,7 +328,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
- uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+ uint64_t NumBits = VE.computeBitsRequiredForTypeIndicies();
// Abbrev for TYPE_CODE_POINTER.
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
@@ -480,13 +486,13 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
case GlobalValue::ExternalLinkage:
return 0;
case GlobalValue::WeakAnyLinkage:
- return 1;
+ return 16;
case GlobalValue::AppendingLinkage:
return 2;
case GlobalValue::InternalLinkage:
return 3;
case GlobalValue::LinkOnceAnyLinkage:
- return 4;
+ return 18;
case GlobalValue::ExternalWeakLinkage:
return 7;
case GlobalValue::CommonLinkage:
@@ -494,9 +500,9 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
case GlobalValue::PrivateLinkage:
return 9;
case GlobalValue::WeakODRLinkage:
- return 10;
+ return 17;
case GlobalValue::LinkOnceODRLinkage:
- return 11;
+ return 19;
case GlobalValue::AvailableExternallyLinkage:
return 12;
}
@@ -549,11 +555,13 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
}
static void writeComdats(const ValueEnumerator &VE, BitstreamWriter &Stream) {
- SmallVector<uint8_t, 64> Vals;
+ SmallVector<uint16_t, 64> Vals;
for (const Comdat *C : VE.getComdats()) {
// COMDAT: [selection_kind, name]
Vals.push_back(getEncodedComdatSelectionKind(*C));
- Vals.push_back(C->getName().size());
+ size_t Size = C->getName().size();
+ assert(isUInt<16>(Size));
+ Vals.push_back(Size);
for (char Chr : C->getName())
Vals.push_back((unsigned char)Chr);
Stream.EmitRecord(bitc::MODULE_CODE_COMDAT, Vals, /*AbbrevToUse=*/0);
@@ -584,7 +592,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
unsigned MaxGlobalType = 0;
for (const GlobalValue &GV : M->globals()) {
MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
- MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+ MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
if (GV.hasSection()) {
// Give section names unique ID's.
unsigned &Entry = SectionMap[GV.getSection()];
@@ -625,10 +633,12 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
Log2_32_Ceil(MaxGlobalType+1)));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constant.
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer.
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Linkage.
- if (MaxAlignment == 0) // Alignment.
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddrSpace << 2
+ //| explicitType << 1
+ //| constant
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer.
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage.
+ if (MaxAlignment == 0) // Alignment.
Abbv->Add(BitCodeAbbrevOp(0));
else {
unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
@@ -651,9 +661,10 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
// GLOBALVAR: [type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
- // unnamed_addr, externally_initialized, dllstorageclass]
- Vals.push_back(VE.getTypeID(GV.getType()));
- Vals.push_back(GV.isConstant());
+ // unnamed_addr, externally_initialized, dllstorageclass,
+ // comdat]
+ Vals.push_back(VE.getTypeID(GV.getValueType()));
+ Vals.push_back(GV.getType()->getAddressSpace() << 2 | 2 | GV.isConstant());
Vals.push_back(GV.isDeclaration() ? 0 :
(VE.getValueID(GV.getInitializer()) + 1));
Vals.push_back(getEncodedLinkage(GV));
@@ -683,7 +694,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
// section, visibility, gc, unnamed_addr, prologuedata,
// dllstorageclass, comdat, prefixdata]
- Vals.push_back(VE.getTypeID(F.getType()));
+ Vals.push_back(VE.getTypeID(F.getFunctionType()));
Vals.push_back(F.getCallingConv());
Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
@@ -760,26 +771,22 @@ static void WriteValueAsMetadata(const ValueAsMetadata *MD,
Record.clear();
}
-static void WriteMDNode(const MDNode *N,
- const ValueEnumerator &VE,
- BitstreamWriter &Stream,
- SmallVectorImpl<uint64_t> &Record) {
+static void WriteMDTuple(const MDTuple *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
Metadata *MD = N->getOperand(i);
- if (!MD) {
- Record.push_back(0);
- continue;
- }
- assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata");
- Record.push_back(VE.getMetadataID(MD) + 1);
+ assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+ "Unexpected function-local metadata");
+ Record.push_back(VE.getMetadataOrNullID(MD));
}
Stream.EmitRecord(N->isDistinct() ? bitc::METADATA_DISTINCT_NODE
: bitc::METADATA_NODE,
- Record);
+ Record, Abbrev);
Record.clear();
}
-static void WriteMDLocation(const MDLocation *N, const ValueEnumerator &VE,
+static void WriteDILocation(const DILocation *N, const ValueEnumerator &VE,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -787,17 +794,355 @@ static void WriteMDLocation(const MDLocation *N, const ValueEnumerator &VE,
Record.push_back(N->getLine());
Record.push_back(N->getColumn());
Record.push_back(VE.getMetadataID(N->getScope()));
-
- // Always emit the inlined-at location, even though it's optional.
- if (Metadata *InlinedAt = N->getInlinedAt())
- Record.push_back(VE.getMetadataID(InlinedAt) + 1);
- else
- Record.push_back(0);
+ Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
Record.clear();
}
+static void WriteGenericDINode(const GenericDINode *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(0); // Per-tag version field; unused for now.
+
+ for (auto &I : N->operands())
+ Record.push_back(VE.getMetadataOrNullID(I));
+
+ Stream.EmitRecord(bitc::METADATA_GENERIC_DEBUG, Record, Abbrev);
+ Record.clear();
+}
+
+static uint64_t rotateSign(int64_t I) {
+ uint64_t U = I;
+ return I < 0 ? ~(U << 1) : U << 1;
+}
+
+static void WriteDISubrange(const DISubrange *N, const ValueEnumerator &,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getCount());
+ Record.push_back(rotateSign(N->getLowerBound()));
+
+ Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIEnumerator(const DIEnumerator *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(rotateSign(N->getValue()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+
+ Stream.EmitRecord(bitc::METADATA_ENUMERATOR, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIBasicType(const DIBasicType *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getEncoding());
+
+ Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIDerivedType(const DIDerivedType *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getOffsetInBits());
+ Record.push_back(N->getFlags());
+ Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));
+
+ Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDICompositeType(const DICompositeType *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getOffsetInBits());
+ Record.push_back(N->getFlags());
+ Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
+ Record.push_back(N->getRuntimeLang());
+ Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));
+ Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
+
+ Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDISubroutineType(const DISubroutineType *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getFlags());
+ Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get()));
+
+ Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIFile(const DIFile *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawFilename()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory()));
+
+ Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDICompileUnit(const DICompileUnit *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getSourceLanguage());
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawProducer()));
+ Record.push_back(N->isOptimized());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawFlags()));
+ Record.push_back(N->getRuntimeVersion());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSplitDebugFilename()));
+ Record.push_back(N->getEmissionKind());
+ Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getSubprograms().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get()));
+ Record.push_back(N->getDWOId());
+
+ Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDISubprogram(const DISubprogram *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+ Record.push_back(N->isLocalToUnit());
+ Record.push_back(N->isDefinition());
+ Record.push_back(N->getScopeLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getContainingType()));
+ Record.push_back(N->getVirtuality());
+ Record.push_back(N->getVirtualIndex());
+ Record.push_back(N->getFlags());
+ Record.push_back(N->isOptimized());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawFunction()));
+ Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
+ Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
+ Record.push_back(VE.getMetadataOrNullID(N->getVariables().get()));
+
+ Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDILexicalBlock(const DILexicalBlock *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(N->getColumn());
+
+ Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDILexicalBlockFile(const DILexicalBlockFile *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getDiscriminator());
+
+ Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK_FILE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(N->getLine());
+
+ Stream.EmitRecord(bitc::METADATA_NAMESPACE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDITemplateTypeParameter(const DITemplateTypeParameter *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+
+ Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDITemplateValueParameter(const DITemplateValueParameter *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+ Record.push_back(VE.getMetadataOrNullID(N->getValue()));
+
+ Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIGlobalVariable(const DIGlobalVariable *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+ Record.push_back(N->isLocalToUnit());
+ Record.push_back(N->isDefinition());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawVariable()));
+ Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
+
+ Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDILocalVariable(const DILocalVariable *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+ Record.push_back(N->getArg());
+ Record.push_back(N->getFlags());
+
+ Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIExpression(const DIExpression *N, const ValueEnumerator &,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.reserve(N->getElements().size() + 1);
+
+ Record.push_back(N->isDistinct());
+ Record.append(N->elements_begin(), N->elements_end());
+
+ Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIObjCProperty(const DIObjCProperty *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSetterName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawGetterName()));
+ Record.push_back(N->getAttributes());
+ Record.push_back(VE.getMetadataOrNullID(N->getType()));
+
+ Stream.EmitRecord(bitc::METADATA_OBJC_PROPERTY, Record, Abbrev);
+ Record.clear();
+}
+
+static void WriteDIImportedEntity(const DIImportedEntity *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getEntity()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+
+ Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev);
+ Record.clear();
+}
+
static void WriteModuleMetadata(const Module *M,
const ValueEnumerator &VE,
BitstreamWriter &Stream) {
@@ -817,8 +1162,11 @@ static void WriteModuleMetadata(const Module *M,
MDSAbbrev = Stream.EmitAbbrev(Abbv);
}
- unsigned LocAbbrev = 0;
- if (VE.hasMDLocation()) {
+ // Initialize MDNode abbreviations.
+#define HANDLE_MDNODE_LEAF(CLASS) unsigned CLASS##Abbrev = 0;
+#include "llvm/IR/Metadata.def"
+
+ if (VE.hasDILocation()) {
// Abbrev for METADATA_LOCATION.
//
// Assume the column is usually under 128, and always output the inlined-at
@@ -830,7 +1178,23 @@ static void WriteModuleMetadata(const Module *M,
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
- LocAbbrev = Stream.EmitAbbrev(Abbv);
+ DILocationAbbrev = Stream.EmitAbbrev(Abbv);
+ }
+
+ if (VE.hasGenericDINode()) {
+ // Abbrev for METADATA_GENERIC_DEBUG.
+ //
+ // Assume the column is usually under 128, and always output the inlined-at
+ // location (it's never more expensive than building an array size 1).
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_GENERIC_DEBUG));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ GenericDINodeAbbrev = Stream.EmitAbbrev(Abbv);
}
unsigned NameAbbrev = 0;
@@ -845,13 +1209,18 @@ static void WriteModuleMetadata(const Module *M,
SmallVector<uint64_t, 64> Record;
for (const Metadata *MD : MDs) {
- if (const MDLocation *Loc = dyn_cast<MDLocation>(MD)) {
- WriteMDLocation(Loc, VE, Stream, Record, LocAbbrev);
- continue;
- }
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
- WriteMDNode(N, VE, Stream, Record);
- continue;
+ assert(N->isResolved() && "Expected forward references to be resolved");
+
+ switch (N->getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \
+ continue;
+#include "llvm/IR/Metadata.def"
+ }
}
if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
WriteValueAsMetadata(MDC, VE, Stream, Record);
@@ -914,6 +1283,15 @@ static void WriteMetadataAttachment(const Function &F,
// Write metadata attachments
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ F.getAllMetadata(MDs);
+ if (!MDs.empty()) {
+ for (const auto &I : MDs) {
+ Record.push_back(I.first);
+ Record.push_back(VE.getMetadataID(I.second));
+ }
+ Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+ Record.clear();
+ }
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
@@ -1031,14 +1409,12 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
// Add the asm string.
const std::string &AsmStr = IA->getAsmString();
Record.push_back(AsmStr.size());
- for (unsigned i = 0, e = AsmStr.size(); i != e; ++i)
- Record.push_back(AsmStr[i]);
+ Record.append(AsmStr.begin(), AsmStr.end());
// Add the constraint string.
const std::string &ConstraintStr = IA->getConstraintString();
Record.push_back(ConstraintStr.size());
- for (unsigned i = 0, e = ConstraintStr.size(); i != e; ++i)
- Record.push_back(ConstraintStr[i]);
+ Record.append(ConstraintStr.begin(), ConstraintStr.end());
Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
Record.clear();
continue;
@@ -1162,15 +1538,18 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
Record.push_back(Flags);
}
break;
- case Instruction::GetElementPtr:
+ case Instruction::GetElementPtr: {
Code = bitc::CST_CODE_CE_GEP;
- if (cast<GEPOperator>(C)->isInBounds())
+ const auto *GO = cast<GEPOperator>(C);
+ if (GO->isInBounds())
Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+ Record.push_back(VE.getTypeID(GO->getSourceElementType()));
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
Record.push_back(VE.getValueID(C->getOperand(i)));
}
break;
+ }
case Instruction::Select:
Code = bitc::CST_CODE_CE_SELECT;
Record.push_back(VE.getValueID(C->getOperand(0)));
@@ -1316,19 +1695,21 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
break;
- case Instruction::GetElementPtr:
+ case Instruction::GetElementPtr: {
Code = bitc::FUNC_CODE_INST_GEP;
- if (cast<GEPOperator>(&I)->isInBounds())
- Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
+ AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
+ auto &GEPInst = cast<GetElementPtrInst>(I);
+ Vals.push_back(GEPInst.isInBounds());
+ Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType()));
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
break;
+ }
case Instruction::ExtractValue: {
Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
const ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
- for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)
- Vals.push_back(*i);
+ Vals.append(EVI->idx_begin(), EVI->idx_end());
break;
}
case Instruction::InsertValue: {
@@ -1336,8 +1717,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
const InsertValueInst *IVI = cast<InsertValueInst>(&I);
- for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
- Vals.push_back(*i);
+ Vals.append(IVI->idx_begin(), IVI->idx_end());
break;
}
case Instruction::Select:
@@ -1423,15 +1803,15 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::Invoke: {
const InvokeInst *II = cast<InvokeInst>(&I);
- const Value *Callee(II->getCalledValue());
- PointerType *PTy = cast<PointerType>(Callee->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ const Value *Callee = II->getCalledValue();
+ FunctionType *FTy = II->getFunctionType();
Code = bitc::FUNC_CODE_INST_INVOKE;
Vals.push_back(VE.getAttributeID(II->getAttributes()));
- Vals.push_back(II->getCallingConv());
+ Vals.push_back(II->getCallingConv() | 1 << 13);
Vals.push_back(VE.getValueID(II->getNormalDest()));
Vals.push_back(VE.getValueID(II->getUnwindDest()));
+ Vals.push_back(VE.getTypeID(FTy));
PushValueAndType(Callee, InstID, Vals, VE);
// Emit value #'s for the fixed parameters.
@@ -1492,15 +1872,16 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::Alloca: {
Code = bitc::FUNC_CODE_INST_ALLOCA;
- Vals.push_back(VE.getTypeID(I.getType()));
+ const AllocaInst &AI = cast<AllocaInst>(I);
+ Vals.push_back(VE.getTypeID(AI.getAllocatedType()));
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
- const AllocaInst &AI = cast<AllocaInst>(I);
unsigned AlignRecord = Log2_32(AI.getAlignment()) + 1;
assert(Log2_32(Value::MaximumAlignment) + 1 < 1 << 5 &&
"not enough bits for maximum alignment");
assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64");
AlignRecord |= AI.isUsedWithInAlloca() << 5;
+ AlignRecord |= 1 << 6;
Vals.push_back(AlignRecord);
break;
}
@@ -1514,6 +1895,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr
AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
}
+ Vals.push_back(VE.getTypeID(I.getType()));
Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
Vals.push_back(cast<LoadInst>(I).isVolatile());
if (cast<LoadInst>(I).isAtomic()) {
@@ -1527,7 +1909,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
else
Code = bitc::FUNC_CODE_INST_STORE;
PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
- pushValue(I.getOperand(0), InstID, Vals, VE); // val.
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE); // valty + val
Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
Vals.push_back(cast<StoreInst>(I).isVolatile());
if (cast<StoreInst>(I).isAtomic()) {
@@ -1538,7 +1920,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::AtomicCmpXchg:
Code = bitc::FUNC_CODE_INST_CMPXCHG;
PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr
- pushValue(I.getOperand(1), InstID, Vals, VE); // cmp.
+ PushValueAndType(I.getOperand(1), InstID, Vals, VE); // cmp.
pushValue(I.getOperand(2), InstID, Vals, VE); // newval.
Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
Vals.push_back(GetEncodedOrdering(
@@ -1567,14 +1949,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::Call: {
const CallInst &CI = cast<CallInst>(I);
- PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ FunctionType *FTy = CI.getFunctionType();
Code = bitc::FUNC_CODE_INST_CALL;
Vals.push_back(VE.getAttributeID(CI.getAttributes()));
Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) |
- unsigned(CI.isMustTailCall()) << 14);
+ unsigned(CI.isMustTailCall()) << 14 | 1 << 15);
+ Vals.push_back(VE.getTypeID(FTy));
PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee
// Emit value #'s for the fixed parameters.
@@ -1673,15 +2055,16 @@ static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order,
else
Code = bitc::USELIST_CODE_DEFAULT;
- SmallVector<uint64_t, 64> Record;
- for (unsigned I : Order.Shuffle)
- Record.push_back(I);
+ SmallVector<uint64_t, 64> Record(Order.Shuffle.begin(), Order.Shuffle.end());
Record.push_back(VE.getValueID(Order.V));
Stream.EmitRecord(Code, Record);
}
static void WriteUseListBlock(const Function *F, ValueEnumerator &VE,
BitstreamWriter &Stream) {
+ assert(VE.shouldPreserveUseListOrder() &&
+ "Expected to be preserving use-list order");
+
auto hasMore = [&]() {
return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F;
};
@@ -1722,9 +2105,9 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
// Keep a running idea of what the instruction ID is.
unsigned InstID = CstEnd;
- bool NeedsMetadataAttachment = false;
+ bool NeedsMetadataAttachment = F.hasMetadata();
- DebugLoc LastDL;
+ DILocation *LastDL = nullptr;
// Finally, emit all the instructions, in order.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
@@ -1739,26 +2122,24 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
// If the instruction has a debug location, emit it.
- DebugLoc DL = I->getDebugLoc();
- if (DL.isUnknown()) {
- // nothing todo.
- } else if (DL == LastDL) {
+ DILocation *DL = I->getDebugLoc();
+ if (!DL)
+ continue;
+
+ if (DL == LastDL) {
// Just repeat the same debug loc as last time.
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
- } else {
- MDNode *Scope, *IA;
- DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
- assert(Scope && "Expected valid scope");
-
- Vals.push_back(DL.getLine());
- Vals.push_back(DL.getCol());
- Vals.push_back(Scope ? VE.getMetadataID(Scope) + 1 : 0);
- Vals.push_back(IA ? VE.getMetadataID(IA) + 1 : 0);
- Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
- Vals.clear();
-
- LastDL = DL;
+ continue;
}
+
+ Vals.push_back(DL->getLine());
+ Vals.push_back(DL->getColumn());
+ Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+ Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+ Vals.clear();
+
+ LastDL = DL;
}
// Emit names for all the instructions etc.
@@ -1766,7 +2147,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
if (NeedsMetadataAttachment)
WriteMetadataAttachment(F, VE, Stream);
- if (shouldPreserveBitcodeUseListOrder())
+ if (VE.shouldPreserveUseListOrder())
WriteUseListBlock(&F, VE, Stream);
VE.purgeFunction();
Stream.ExitBlock();
@@ -1827,7 +2208,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ VE.computeBitsRequiredForTypeIndicies()));
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
Abbv) != CONSTANTS_SETTYPE_ABBREV)
llvm_unreachable("Unexpected abbrev ordering!");
@@ -1847,7 +2228,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // cast opc
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // typeid
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ VE.computeBitsRequiredForTypeIndicies()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
@@ -1868,6 +2249,8 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
+ VE.computeBitsRequiredForTypeIndicies()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
@@ -1900,7 +2283,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ VE.computeBitsRequiredForTypeIndicies()));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
Abbv) != FUNCTION_INST_CAST_ABBREV)
@@ -1929,12 +2312,25 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
llvm_unreachable("Unexpected abbrev ordering!");
}
+ {
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty
+ Log2_32_Ceil(VE.getTypes().size() + 1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
+ FUNCTION_INST_GEP_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
Stream.ExitBlock();
}
/// WriteModule - Emit the specified module to the bitstream.
-static void WriteModule(const Module *M, BitstreamWriter &Stream) {
+static void WriteModule(const Module *M, BitstreamWriter &Stream,
+ bool ShouldPreserveUseListOrder) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
SmallVector<unsigned, 1> Vals;
@@ -1943,7 +2339,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
// Analyze the module, enumerating globals, functions, etc.
- ValueEnumerator VE(*M);
+ ValueEnumerator VE(*M, ShouldPreserveUseListOrder);
// Emit blockinfo, which defines the standard abbreviations etc.
WriteBlockInfo(VE, Stream);
@@ -1976,7 +2372,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
// Emit module-level use-lists.
- if (shouldPreserveBitcodeUseListOrder())
+ if (VE.shouldPreserveUseListOrder())
WriteUseListBlock(nullptr, VE, Stream);
// Emit function bodies.
@@ -2062,7 +2458,8 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
-void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
+void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
+ bool ShouldPreserveUseListOrder) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256*1024);
@@ -2085,7 +2482,7 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
Stream.Emit(0xD, 4);
// Emit the module.
- WriteModule(M, Stream);
+ WriteModule(M, Stream, ShouldPreserveUseListOrder);
}
if (TT.isOSDarwin())
diff --git a/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index 25456a456217..3165743576ec 100644
--- a/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -19,22 +19,25 @@
using namespace llvm;
PreservedAnalyses BitcodeWriterPass::run(Module &M) {
- WriteBitcodeToFile(&M, OS);
+ WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder);
return PreservedAnalyses::all();
}
namespace {
class WriteBitcodePass : public ModulePass {
raw_ostream &OS; // raw_ostream to print on
+ bool ShouldPreserveUseListOrder;
+
public:
static char ID; // Pass identification, replacement for typeid
- explicit WriteBitcodePass(raw_ostream &o)
- : ModulePass(ID), OS(o) {}
+ explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder)
+ : ModulePass(ID), OS(o),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
const char *getPassName() const override { return "Bitcode Writer"; }
bool runOnModule(Module &M) override {
- WriteBitcodeToFile(&M, OS);
+ WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder);
return false;
}
};
@@ -42,6 +45,7 @@ namespace {
char WriteBitcodePass::ID = 0;
-ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str) {
- return new WriteBitcodePass(Str);
+ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
+ bool ShouldPreserveUseListOrder) {
+ return new WriteBitcodePass(Str, ShouldPreserveUseListOrder);
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 27a63d8fefc6..6c517f5ed8d0 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -282,9 +283,11 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
return V.first->getType()->isIntOrIntVectorTy();
}
-ValueEnumerator::ValueEnumerator(const Module &M)
- : HasMDString(false), HasMDLocation(false) {
- if (shouldPreserveBitcodeUseListOrder())
+ValueEnumerator::ValueEnumerator(const Module &M,
+ bool ShouldPreserveUseListOrder)
+ : HasMDString(false), HasDILocation(false), HasGenericDINode(false),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
+ if (ShouldPreserveUseListOrder)
UseListOrders = predictUseListOrder(M);
// Enumerate the global variables.
@@ -345,6 +348,11 @@ ValueEnumerator::ValueEnumerator(const Module &M)
for (const Argument &A : F.args())
EnumerateType(A.getType());
+ // Enumerate metadata attached to this function.
+ F.getAllMetadata(MDs);
+ for (const auto &I : MDs)
+ EnumerateMetadata(I.second);
+
for (const BasicBlock &BB : F)
for (const Instruction &I : BB) {
for (const Use &Op : I.operands()) {
@@ -372,12 +380,10 @@ ValueEnumerator::ValueEnumerator(const Module &M)
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
- if (!I.getDebugLoc().isUnknown()) {
- MDNode *Scope, *IA;
- I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext());
- if (Scope) EnumerateMetadata(Scope);
- if (IA) EnumerateMetadata(IA);
- }
+ // Don't enumerate the location directly -- it has a special record
+ // type -- but enumerate its operands.
+ if (DILocation *L = I.getDebugLoc())
+ EnumerateMDNodeOperands(L);
}
}
@@ -410,12 +416,6 @@ unsigned ValueEnumerator::getValueID(const Value *V) const {
return I->second-1;
}
-unsigned ValueEnumerator::getMetadataID(const Metadata *MD) const {
- auto I = MDValueMap.find(MD);
- assert(I != MDValueMap.end() && "Metadata not in slotcalculator!");
- return I->second - 1;
-}
-
void ValueEnumerator::dump() const {
print(dbgs(), ValueMap, "Default");
dbgs() << '\n';
@@ -468,7 +468,7 @@ void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map,
void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
- if (shouldPreserveBitcodeUseListOrder())
+ if (ShouldPreserveUseListOrder)
// Optimizing constants makes the use-list order difficult to predict.
// Disable it for now when trying to preserve the order.
return;
@@ -548,7 +548,8 @@ void ValueEnumerator::EnumerateMetadata(const Metadata *MD) {
EnumerateValue(C->getValue());
HasMDString |= isa<MDString>(MD);
- HasMDLocation |= isa<MDLocation>(MD);
+ HasDILocation |= isa<DILocation>(MD);
+ HasGenericDINode |= isa<GenericDINode>(MD);
// Replace the dummy ID inserted above with the correct one. MDValueMap may
// have changed by inserting operands, so we need a fresh lookup here.
@@ -807,3 +808,7 @@ unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
return getGlobalBasicBlockID(BB);
}
+
+uint64_t ValueEnumerator::computeBitsRequiredForTypeIndicies() const {
+ return Log2_32_Ceil(getTypes().size() + 1);
+}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index d363c1be0dda..92d166e3ba92 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -65,7 +65,9 @@ private:
typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
MetadataMapType MDValueMap;
bool HasMDString;
- bool HasMDLocation;
+ bool HasDILocation;
+ bool HasGenericDINode;
+ bool ShouldPreserveUseListOrder;
typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
AttributeGroupMapType AttributeGroupMap;
@@ -98,10 +100,10 @@ private:
unsigned FirstFuncConstantID;
unsigned FirstInstID;
- ValueEnumerator(const ValueEnumerator &) LLVM_DELETED_FUNCTION;
- void operator=(const ValueEnumerator &) LLVM_DELETED_FUNCTION;
+ ValueEnumerator(const ValueEnumerator &) = delete;
+ void operator=(const ValueEnumerator &) = delete;
public:
- ValueEnumerator(const Module &M);
+ ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder);
void dump() const;
void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
@@ -109,10 +111,20 @@ public:
const char *Name) const;
unsigned getValueID(const Value *V) const;
- unsigned getMetadataID(const Metadata *V) const;
+ unsigned getMetadataID(const Metadata *MD) const {
+ auto ID = getMetadataOrNullID(MD);
+ assert(ID != 0 && "Metadata not in slotcalculator!");
+ return ID - 1;
+ }
+ unsigned getMetadataOrNullID(const Metadata *MD) const {
+ return MDValueMap.lookup(MD);
+ }
bool hasMDString() const { return HasMDString; }
- bool hasMDLocation() const { return HasMDLocation; }
+ bool hasDILocation() const { return HasDILocation; }
+ bool hasGenericDINode() const { return HasGenericDINode; }
+
+ bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; }
unsigned getTypeID(Type *T) const {
TypeMapType::const_iterator I = TypeMap.find(T);
@@ -173,6 +185,7 @@ public:
///
void incorporateFunction(const Function &F);
void purgeFunction();
+ uint64_t computeBitsRequiredForTypeIndicies() const;
private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);