summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Bitcode')
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitReader.cpp8
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp2271
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h365
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp40
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp607
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp18
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp89
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h27
8 files changed, 2233 insertions, 1192 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp
index 868fbf0..289c76e 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp
@@ -39,7 +39,7 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
raw_string_ostream Stream(Message);
DiagnosticPrinterRawOStream DP(Stream);
- ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(
+ ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(
Buf, Ctx, [&](const DiagnosticInfo &DI) { DI.print(DP); });
if (ModuleOrErr.getError()) {
if (OutMessage) {
@@ -50,7 +50,7 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
return 1;
}
- *OutModule = wrap(ModuleOrErr.get());
+ *OutModule = wrap(ModuleOrErr.get().release());
return 0;
}
@@ -64,7 +64,7 @@ LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
std::string Message;
std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
- ErrorOr<Module *> ModuleOrErr =
+ ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef));
Owner.release();
@@ -75,7 +75,7 @@ LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
return 1;
}
- *OutM = wrap(ModuleOrErr.get());
+ *OutM = wrap(ModuleOrErr.get().release());
return 0;
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 3d9546f..0cadd6c 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -8,32 +8,377 @@
//===----------------------------------------------------------------------===//
#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;
+
+ /// 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.emplace_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);
+
+ /// 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 = nullptr;
+ std::unique_ptr<MemoryBuffer> Buffer;
+ std::unique_ptr<BitstreamReader> StreamFile;
+ BitstreamCursor Stream;
+ bool IsStreamed;
+ uint64_t NextUnreadBit = 0;
+ bool SeenValueSymbolTable = false;
+
+ 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;
+ std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
+
+ SmallVector<Instruction*, 64> InstsWithTBAATag;
+
+ /// 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;
+
+ /// 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 = false;
+
+ /// 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;
+
+ /// 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 = false;
+
+ /// True if all functions will be materialized, negating the need to process
+ /// (e.g.) blockaddress forward references.
+ bool WillMaterializeAllForwardRefs = false;
+
+ /// 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 = false;
+
+ 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);
+
+ BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context,
+ DiagnosticHandlerFunction DiagnosticHandler);
+ BitcodeReader(LLVMContext &Context,
+ 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(std::unique_ptr<DataStreamer> Streamer,
+ 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();
+ }
+
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ /// 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);
+ }
+
+ /// 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::unique_ptr<DataStreamer> Streamer);
+ std::error_code initStreamFromBuffer();
+ std::error_code initLazyStream(std::unique_ptr<DataStreamer> Streamer);
+ std::error_code findFunctionInStream(
+ Function *F,
+ DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator);
+};
+} // namespace
+
BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC,
DiagnosticSeverity Severity,
const Twine &Msg)
@@ -41,29 +386,35 @@ BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC,
void BitcodeDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; }
-static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler,
+static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler,
std::error_code EC, const Twine &Message) {
BitcodeDiagnosticInfo DI(EC, DS_Error, Message);
DiagnosticHandler(DI);
return EC;
}
-static std::error_code Error(DiagnosticHandlerFunction DiagnosticHandler,
+static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler,
std::error_code EC) {
- return Error(DiagnosticHandler, EC, EC.message());
+ 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);
+std::error_code BitcodeReader::error(BitcodeError E, const Twine &Message) {
+ return ::error(DiagnosticHandler, make_error_code(E), Message);
}
-std::error_code BitcodeReader::Error(const Twine &Message) {
- return ::Error(DiagnosticHandler,
+std::error_code BitcodeReader::error(const Twine &Message) {
+ return ::error(DiagnosticHandler,
make_error_code(BitcodeError::CorruptedBitcode), Message);
}
-std::error_code BitcodeReader::Error(BitcodeError E) {
- return ::Error(DiagnosticHandler, make_error_code(E));
+std::error_code BitcodeReader::error(BitcodeError E) {
+ return ::error(DiagnosticHandler, make_error_code(E));
}
static DiagnosticHandlerFunction getDiagHandler(DiagnosticHandlerFunction F,
@@ -73,21 +424,19 @@ static DiagnosticHandlerFunction getDiagHandler(DiagnosticHandlerFunction F,
return [&C](const DiagnosticInfo &DI) { C.diagnose(DI); };
}
-BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+BitcodeReader::BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context,
DiagnosticHandlerFunction DiagnosticHandler)
- : Context(C), DiagnosticHandler(getDiagHandler(DiagnosticHandler, C)),
- TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
- NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
- MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ : Context(Context),
+ DiagnosticHandler(getDiagHandler(DiagnosticHandler, Context)),
+ Buffer(Buffer), IsStreamed(false), ValueList(Context),
+ MDValueList(Context) {}
-BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C,
+BitcodeReader::BitcodeReader(LLVMContext &Context,
DiagnosticHandlerFunction DiagnosticHandler)
- : Context(C), DiagnosticHandler(getDiagHandler(DiagnosticHandler, C)),
- TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer),
- NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
- MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ : Context(Context),
+ DiagnosticHandler(getDiagHandler(DiagnosticHandler, Context)),
+ Buffer(nullptr), IsStreamed(true), ValueList(Context),
+ MDValueList(Context) {}
std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
if (WillMaterializeAllForwardRefs)
@@ -109,7 +458,7 @@ std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
// isn't a trivial way to check if a function will have a body without a
// linear search through FunctionsWithBodies, so just check it here.
if (!F->isMaterializable())
- return Error("Never resolved function from blockaddress");
+ return error("Never resolved function from blockaddress");
// Try to materialize F.
if (std::error_code EC = materialize(F))
@@ -122,7 +471,7 @@ std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
return std::error_code();
}
-void BitcodeReader::FreeState() {
+void BitcodeReader::freeState() {
Buffer = nullptr;
std::vector<Type*>().swap(TypeList);
ValueList.clear();
@@ -133,6 +482,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");
@@ -143,10 +493,9 @@ void BitcodeReader::FreeState() {
// Helper functions to implement forward reference resolution, etc.
//===----------------------------------------------------------------------===//
-/// ConvertToString - Convert a string from a record into an std::string, return
-/// true on failure.
-template<typename StrTy>
-static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
+/// Convert a string from a record into an std::string, return true on failure.
+template <typename StrTy>
+static bool convertToString(ArrayRef<uint64_t> Record, unsigned Idx,
StrTy &Result) {
if (Idx > Record.size())
return true;
@@ -156,19 +505,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 +536,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,10 +544,22 @@ 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;
}
}
-static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
+static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
switch (Val) {
default: // Map unknown visibilities to default.
case 0: return GlobalValue::DefaultVisibility;
@@ -204,7 +569,7 @@ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
}
static GlobalValue::DLLStorageClassTypes
-GetDecodedDLLStorageClass(unsigned Val) {
+getDecodedDLLStorageClass(unsigned Val) {
switch (Val) {
default: // Map unknown values to default.
case 0: return GlobalValue::DefaultStorageClass;
@@ -213,7 +578,7 @@ GetDecodedDLLStorageClass(unsigned Val) {
}
}
-static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
+static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) {
switch (Val) {
case 0: return GlobalVariable::NotThreadLocal;
default: // Map unknown non-zero value to general dynamic.
@@ -224,7 +589,7 @@ static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
}
}
-static int GetDecodedCastOpcode(unsigned Val) {
+static int getDecodedCastOpcode(unsigned Val) {
switch (Val) {
default: return -1;
case bitc::CAST_TRUNC : return Instruction::Trunc;
@@ -242,31 +607,46 @@ static int GetDecodedCastOpcode(unsigned Val) {
case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast;
}
}
-static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
+
+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;
}
}
-static AtomicRMWInst::BinOp GetDecodedRMWOperation(unsigned Val) {
+static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) {
switch (Val) {
default: return AtomicRMWInst::BAD_BINOP;
case bitc::RMW_XCHG: return AtomicRMWInst::Xchg;
@@ -283,7 +663,7 @@ static AtomicRMWInst::BinOp GetDecodedRMWOperation(unsigned Val) {
}
}
-static AtomicOrdering GetDecodedOrdering(unsigned Val) {
+static AtomicOrdering getDecodedOrdering(unsigned Val) {
switch (Val) {
case bitc::ORDERING_NOTATOMIC: return NotAtomic;
case bitc::ORDERING_UNORDERED: return Unordered;
@@ -296,7 +676,7 @@ static AtomicOrdering GetDecodedOrdering(unsigned Val) {
}
}
-static SynchronizationScope GetDecodedSynchScope(unsigned Val) {
+static SynchronizationScope getDecodedSynchScope(unsigned Val) {
switch (Val) {
case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread;
default: // Map unknown scopes to cross-thread.
@@ -320,7 +700,7 @@ static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) {
}
}
-static void UpgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
+static void upgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
switch (Val) {
case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break;
case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break;
@@ -329,31 +709,29 @@ static void UpgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
namespace llvm {
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;
- public:
- // allocate space for exactly one operand
- void *operator new(size_t s) {
- return User::operator new(s, 1);
- }
- explicit ConstantPlaceHolder(Type *Ty, LLVMContext& Context)
+/// \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 &) = delete;
+
+public:
+ // allocate space for exactly one operand
+ void *operator new(size_t s) { return User::operator new(s, 1); }
+ explicit ConstantPlaceHolder(Type *Ty, LLVMContext &Context)
: ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) {
- Op<0>() = UndefValue::get(Type::getInt32Ty(Context));
- }
-
- /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
- static bool classof(const Value *V) {
- return isa<ConstantExpr>(V) &&
- cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
- }
+ Op<0>() = UndefValue::get(Type::getInt32Ty(Context));
+ }
+ /// \brief Methods to support type inquiry through isa, cast, and dyn_cast.
+ static bool classof(const Value *V) {
+ return isa<ConstantExpr>(V) &&
+ cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
+ }
- /// Provide fast operand accessors
- DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- };
-}
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+};
+} // namespace
// FIXME: can we inherit this from ConstantExpr?
template <>
@@ -361,10 +739,9 @@ struct OperandTraits<ConstantPlaceHolder> :
public FixedNumOperandTraits<ConstantPlaceHolder, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
-}
-
+} // namespace llvm
-void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) {
+void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
if (Idx == size()) {
push_back(V);
return;
@@ -399,7 +776,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 +788,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;
}
@@ -427,14 +811,13 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
return V;
}
-/// ResolveConstantForwardRefs - Once all constants are read, this method bulk
-/// resolves any forward references. The idea behind this is that we sometimes
-/// get constants (such as large arrays) which reference *many* forward ref
-/// constants. Replacing each of these causes a lot of thrashing when
-/// building/reuniquing the constant. Instead of doing this, we look at all the
-/// uses and rewrite all the place holders at once for any constant that uses
-/// a placeholder.
-void BitcodeReaderValueList::ResolveConstantForwardRefs() {
+/// Once all constants are read, this method bulk resolves any forward
+/// references. The idea behind this is that we sometimes get constants (such
+/// as large arrays) which reference *many* forward ref constants. Replacing
+/// each of these causes a lot of thrashing when building/reuniquing the
+/// constant. Instead of doing this, we look at all the uses and rewrite all
+/// the place holders at once for any constant that uses a placeholder.
+void BitcodeReaderValueList::resolveConstantForwardRefs() {
// Sort the values by-pointer so that they are efficient to look up with a
// binary search.
std::sort(ResolveConstants.begin(), ResolveConstants.end());
@@ -509,7 +892,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
}
}
-void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
+void BitcodeReaderMDValueList::assignValue(Metadata *MD, unsigned Idx) {
if (Idx == size()) {
push_back(MD);
return;
@@ -525,9 +908,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 +931,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 +948,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.
@@ -626,12 +1011,12 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B,
(EncodedAttrs & 0xffff));
}
-std::error_code BitcodeReader::ParseAttributeBlock() {
+std::error_code BitcodeReader::parseAttributeBlock() {
if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
if (!MAttributes.empty())
- return Error("Invalid multiple blocks");
+ return error("Invalid multiple blocks");
SmallVector<uint64_t, 64> Record;
@@ -644,7 +1029,7 @@ std::error_code BitcodeReader::ParseAttributeBlock() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
case BitstreamEntry::Record:
@@ -660,7 +1045,7 @@ std::error_code BitcodeReader::ParseAttributeBlock() {
case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...]
// FIXME: Remove in 4.0.
if (Record.size() & 1)
- return Error("Invalid record");
+ return error("Invalid record");
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
AttrBuilder B;
@@ -685,7 +1070,7 @@ std::error_code BitcodeReader::ParseAttributeBlock() {
}
// Returns Attribute::None on unrecognized codes.
-static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
+static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
switch (Code) {
default:
return Attribute::None;
@@ -701,6 +1086,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 +1118,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:
@@ -759,6 +1148,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
return Attribute::StackProtectReq;
case bitc::ATTR_KIND_STACK_PROTECT_STRONG:
return Attribute::StackProtectStrong;
+ case bitc::ATTR_KIND_SAFESTACK:
+ return Attribute::SafeStack;
case bitc::ATTR_KIND_STRUCT_RET:
return Attribute::StructRet;
case bitc::ATTR_KIND_SANITIZE_ADDRESS:
@@ -774,21 +1165,31 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
}
}
-std::error_code BitcodeReader::ParseAttrKind(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);
+ *Kind = getAttrFromCode(Code);
if (*Kind == Attribute::None)
- return Error(BitcodeError::CorruptedBitcode,
+ return error(BitcodeError::CorruptedBitcode,
"Unknown attribute kind (" + Twine(Code) + ")");
return std::error_code();
}
-std::error_code BitcodeReader::ParseAttributeGroupBlock() {
+std::error_code BitcodeReader::parseAttributeGroupBlock() {
if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
if (!MAttributeGroups.empty())
- return Error("Invalid multiple blocks");
+ return error("Invalid multiple blocks");
SmallVector<uint64_t, 64> Record;
@@ -799,7 +1200,7 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
case BitstreamEntry::Record:
@@ -814,7 +1215,7 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() {
break;
case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...]
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
uint64_t GrpID = Record[0];
uint64_t Idx = Record[1]; // Index of the object this attribute refers to.
@@ -823,13 +1224,13 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() {
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
if (Record[i] == 0) { // Enum attribute
Attribute::AttrKind Kind;
- if (std::error_code EC = ParseAttrKind(Record[++i], &Kind))
+ if (std::error_code EC = parseAttrKind(Record[++i], &Kind))
return EC;
B.addAttribute(Kind);
} else if (Record[i] == 1) { // Integer attribute
Attribute::AttrKind Kind;
- if (std::error_code EC = ParseAttrKind(Record[++i], &Kind))
+ if (std::error_code EC = parseAttrKind(Record[++i], &Kind))
return EC;
if (Kind == Attribute::Alignment)
B.addAlignmentAttr(Record[++i]);
@@ -837,6 +1238,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");
@@ -867,16 +1270,16 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() {
}
}
-std::error_code BitcodeReader::ParseTypeTable() {
+std::error_code BitcodeReader::parseTypeTable() {
if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
- return Error("Invalid record");
+ return error("Invalid record");
- return ParseTypeTableBody();
+ return parseTypeTableBody();
}
-std::error_code BitcodeReader::ParseTypeTableBody() {
+std::error_code BitcodeReader::parseTypeTableBody() {
if (!TypeList.empty())
- return Error("Invalid multiple blocks");
+ return error("Invalid multiple blocks");
SmallVector<uint64_t, 64> Record;
unsigned NumRecords = 0;
@@ -890,10 +1293,10 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
if (NumRecords != TypeList.size())
- return Error("Malformed block");
+ return error("Malformed block");
return std::error_code();
case BitstreamEntry::Record:
// The interesting case.
@@ -905,12 +1308,12 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
Type *ResultTy = nullptr;
switch (Stream.readRecord(Entry.ID, Record)) {
default:
- return Error("Invalid value");
+ return error("Invalid value");
case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
// TYPE_CODE_NUMENTRY contains a count of the number of types in the
// type list. This allows us to reserve space.
if (Record.size() < 1)
- return Error("Invalid record");
+ return error("Invalid record");
TypeList.resize(Record[0]);
continue;
case bitc::TYPE_CODE_VOID: // VOID
@@ -943,22 +1346,28 @@ 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");
+ 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)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned AddressSpace = 0;
if (Record.size() == 2)
AddressSpace = Record[1];
ResultTy = getTypeByID(Record[0]);
- if (!ResultTy)
- return Error("Invalid type");
+ if (!ResultTy ||
+ !PointerType::isValidElementType(ResultTy))
+ return error("Invalid type");
ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
}
@@ -966,7 +1375,7 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
// FIXME: attrid is dead, remove it in LLVM 4.0
// FUNCTION: [vararg, attrid, retty, paramty x N]
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<Type*, 8> ArgTys;
for (unsigned i = 3, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
@@ -977,7 +1386,7 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
ResultTy = getTypeByID(Record[2]);
if (!ResultTy || ArgTys.size() < Record.size()-3)
- return Error("Invalid type");
+ return error("Invalid type");
ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
@@ -985,25 +1394,28 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
case bitc::TYPE_CODE_FUNCTION: {
// FUNCTION: [vararg, retty, paramty x N]
if (Record.size() < 2)
- return Error("Invalid record");
+ 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;
}
ResultTy = getTypeByID(Record[1]);
if (!ResultTy || ArgTys.size() < Record.size()-2)
- return Error("Invalid type");
+ return error("Invalid type");
ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
}
case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N]
if (Record.size() < 1)
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<Type*, 8> EltTys;
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
@@ -1012,21 +1424,21 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
break;
}
if (EltTys.size() != Record.size()-1)
- return Error("Invalid type");
+ return error("Invalid type");
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N]
- if (ConvertToString(Record, 0, TypeName))
- return Error("Invalid record");
+ if (convertToString(Record, 0, TypeName))
+ return error("Invalid record");
continue;
case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
if (Record.size() < 1)
- return Error("Invalid record");
+ return error("Invalid record");
if (NumRecords >= TypeList.size())
- return Error("Invalid TYPE table");
+ return error("Invalid TYPE table");
// Check to see if this was forward referenced, if so fill in the temp.
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
@@ -1045,17 +1457,17 @@ std::error_code BitcodeReader::ParseTypeTableBody() {
break;
}
if (EltTys.size() != Record.size()-1)
- return Error("Invalid record");
+ return error("Invalid record");
Res->setBody(EltTys, Record[0]);
ResultTy = Res;
break;
}
case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: []
if (Record.size() != 1)
- return Error("Invalid record");
+ return error("Invalid record");
if (NumRecords >= TypeList.size())
- return Error("Invalid TYPE table");
+ return error("Invalid TYPE table");
// Check to see if this was forward referenced, if so fill in the temp.
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
@@ -1070,36 +1482,42 @@ 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
- return Error("Invalid type");
+ return error("Invalid record");
+ 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
- return Error("Invalid type");
+ return error("Invalid record");
+ if (Record[0] == 0)
+ return error("Invalid vector length");
+ 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");
+ 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;
}
}
-std::error_code BitcodeReader::ParseValueSymbolTable() {
+std::error_code BitcodeReader::parseValueSymbolTable() {
if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<uint64_t, 64> Record;
+ Triple TT(TheModule->getTargetTriple());
+
// Read all the records for this value table.
SmallString<128> ValueName;
while (1) {
@@ -1108,7 +1526,7 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
case BitstreamEntry::Record:
@@ -1122,23 +1540,31 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
default: // Default behavior: unknown type.
break;
case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N]
- if (ConvertToString(Record, 1, ValueName))
- return Error("Invalid record");
+ if (convertToString(Record, 1, ValueName))
+ return error("Invalid record");
unsigned ValueID = Record[0];
if (ValueID >= ValueList.size() || !ValueList[ValueID])
- return Error("Invalid record");
+ return error("Invalid record");
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;
}
case bitc::VST_CODE_BBENTRY: {
- if (ConvertToString(Record, 1, ValueName))
- return Error("Invalid record");
+ if (convertToString(Record, 1, ValueName))
+ return error("Invalid record");
BasicBlock *BB = getBasicBlock(Record[0]);
if (!BB)
- return Error("Invalid record");
+ return error("Invalid record");
BB->setName(StringRef(ValueName.data(), ValueName.size()));
ValueName.clear();
@@ -1148,14 +1574,33 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
}
}
-std::error_code BitcodeReader::ParseMetadata() {
+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))
- return Error("Invalid record");
+ return error("Invalid record");
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();
@@ -1163,7 +1608,7 @@ std::error_code BitcodeReader::ParseMetadata() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
MDValueList.tryToResolveCycles();
return std::error_code();
@@ -1185,9 +1630,9 @@ std::error_code BitcodeReader::ParseMetadata() {
Record.clear();
Code = Stream.ReadCode();
- // METADATA_NAME is always followed by METADATA_NAMED_NODE.
unsigned NextBitCode = Stream.readRecord(Code, Record);
- assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode;
+ if (NextBitCode != bitc::METADATA_NAMED_NODE)
+ return error("METADATA_NAME not followed by METADATA_NAMED_NODE");
// Read named metadata elements.
unsigned Size = Record.size();
@@ -1195,7 +1640,7 @@ std::error_code BitcodeReader::ParseMetadata() {
for (unsigned i = 0; i != Size; ++i) {
MDNode *MD = dyn_cast_or_null<MDNode>(MDValueList.getValueFwdRef(Record[i]));
if (!MD)
- return Error("Invalid record");
+ return error("Invalid record");
NMD->addOperand(MD);
}
break;
@@ -1205,12 +1650,12 @@ std::error_code BitcodeReader::ParseMetadata() {
// This is a LocalAsMetadata record, the only type of function-local
// metadata.
if (Record.size() % 2 == 1)
- return Error("Invalid record");
+ return error("Invalid record");
// If this isn't a LocalAsMetadata record, we're dropping it. This used
// to be legal, but there's no upgrade path.
auto dropRecord = [&] {
- MDValueList.AssignValue(MDNode::get(Context, None), NextMDValueNo++);
+ MDValueList.assignValue(MDNode::get(Context, None), NextMDValueNo++);
};
if (Record.size() != 2) {
dropRecord();
@@ -1223,7 +1668,7 @@ std::error_code BitcodeReader::ParseMetadata() {
break;
}
- MDValueList.AssignValue(
+ MDValueList.assignValue(
LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
NextMDValueNo++);
break;
@@ -1231,14 +1676,14 @@ std::error_code BitcodeReader::ParseMetadata() {
case bitc::METADATA_OLD_NODE: {
// FIXME: Remove in 4.0.
if (Record.size() % 2 == 1)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned Size = Record.size();
SmallVector<Metadata *, 8> Elts;
for (unsigned i = 0; i != Size; i += 2) {
Type *Ty = getTypeByID(Record[i]);
if (!Ty)
- return Error("Invalid record");
+ return error("Invalid record");
if (Ty->isMetadataTy())
Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
else if (!Ty->isVoidTy()) {
@@ -1250,18 +1695,18 @@ std::error_code BitcodeReader::ParseMetadata() {
} else
Elts.push_back(nullptr);
}
- MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++);
+ MDValueList.assignValue(MDNode::get(Context, Elts), NextMDValueNo++);
break;
}
case bitc::METADATA_VALUE: {
if (Record.size() != 2)
- return Error("Invalid record");
+ return error("Invalid record");
Type *Ty = getTypeByID(Record[0]);
if (Ty->isMetadataTy() || Ty->isVoidTy())
- return Error("Invalid record");
+ return error("Invalid record");
- MDValueList.AssignValue(
+ MDValueList.assignValue(
ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
NextMDValueNo++);
break;
@@ -1274,50 +1719,304 @@ std::error_code BitcodeReader::ParseMetadata() {
Elts.reserve(Record.size());
for (unsigned ID : Record)
Elts.push_back(ID ? MDValueList.getValueFwdRef(ID - 1) : nullptr);
- MDValueList.AssignValue(IsDistinct ? MDNode::getDistinct(Context, Elts)
+ MDValueList.assignValue(IsDistinct ? MDNode::getDistinct(Context, Elts)
: MDNode::get(Context, Elts),
NextMDValueNo++);
break;
}
case bitc::METADATA_LOCATION: {
if (Record.size() != 5)
- return Error("Invalid record");
+ 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);
Metadata *MD = MDString::get(Context, String);
- MDValueList.AssignValue(MD, NextMDValueNo++);
+ MDValueList.assignValue(MD, NextMDValueNo++);
break;
}
case bitc::METADATA_KIND: {
if (Record.size() < 2)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned Kind = Record[0];
SmallString<8> Name(Record.begin()+1, Record.end());
unsigned NewKind = TheModule->getMDKindID(Name.str());
if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
- return Error("Conflicting METADATA_KIND records");
+ return error("Conflicting METADATA_KIND records");
break;
}
}
}
+#undef GET_OR_DISTINCT
}
-/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
-/// the LSB for dense VBR encoding.
+/// Decode a signed value stored with the sign bit in the LSB for dense VBR
+/// encoding.
uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
if ((V & 1) == 0)
return V >> 1;
@@ -1327,18 +2026,19 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
return 1ULL << 63;
}
-/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
-/// values and aliases that we can.
-std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
+/// Resolve all of the initializers for global values and aliases that we can.
+std::error_code BitcodeReader::resolveGlobalAndAliasInits() {
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist;
std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist;
+ std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist;
GlobalInitWorklist.swap(GlobalInits);
AliasInitWorklist.swap(AliasInits);
FunctionPrefixWorklist.swap(FunctionPrefixes);
FunctionPrologueWorklist.swap(FunctionPrologues);
+ FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns);
while (!GlobalInitWorklist.empty()) {
unsigned ValID = GlobalInitWorklist.back().second;
@@ -1349,7 +2049,7 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
GlobalInitWorklist.back().first->setInitializer(C);
else
- return Error("Expected a constant");
+ return error("Expected a constant");
}
GlobalInitWorklist.pop_back();
}
@@ -1359,10 +2059,13 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
if (ValID >= ValueList.size()) {
AliasInits.push_back(AliasInitWorklist.back());
} else {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- AliasInitWorklist.back().first->setAliasee(C);
- else
- return Error("Expected a constant");
+ Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
+ if (!C)
+ return error("Expected a constant");
+ GlobalAlias *Alias = AliasInitWorklist.back().first;
+ if (C->getType() != Alias->getType())
+ return error("Alias and aliasee types don't match");
+ Alias->setAliasee(C);
}
AliasInitWorklist.pop_back();
}
@@ -1375,7 +2078,7 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
FunctionPrefixWorklist.back().first->setPrefixData(C);
else
- return Error("Expected a constant");
+ return error("Expected a constant");
}
FunctionPrefixWorklist.pop_back();
}
@@ -1388,15 +2091,28 @@ std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
FunctionPrologueWorklist.back().first->setPrologueData(C);
else
- return Error("Expected a constant");
+ return error("Expected a constant");
}
FunctionPrologueWorklist.pop_back();
}
+ while (!FunctionPersonalityFnWorklist.empty()) {
+ unsigned ValID = FunctionPersonalityFnWorklist.back().second;
+ if (ValID >= ValueList.size()) {
+ FunctionPersonalityFns.push_back(FunctionPersonalityFnWorklist.back());
+ } else {
+ if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
+ FunctionPersonalityFnWorklist.back().first->setPersonalityFn(C);
+ else
+ return error("Expected a constant");
+ }
+ FunctionPersonalityFnWorklist.pop_back();
+ }
+
return std::error_code();
}
-static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
+static APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
SmallVector<uint64_t, 8> Words(Vals.size());
std::transform(Vals.begin(), Vals.end(), Words.begin(),
BitcodeReader::decodeSignRotatedValue);
@@ -1404,9 +2120,9 @@ static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
return APInt(TypeBits, Words);
}
-std::error_code BitcodeReader::ParseConstants() {
+std::error_code BitcodeReader::parseConstants() {
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<uint64_t, 64> Record;
@@ -1419,14 +2135,14 @@ std::error_code BitcodeReader::ParseConstants() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
if (NextCstNo != ValueList.size())
- return Error("Invalid ronstant reference");
+ return error("Invalid ronstant reference");
// Once all the constants have been read, go through and resolve forward
// references.
- ValueList.ResolveConstantForwardRefs();
+ ValueList.resolveConstantForwardRefs();
return std::error_code();
case BitstreamEntry::Record:
// The interesting case.
@@ -1444,9 +2160,9 @@ std::error_code BitcodeReader::ParseConstants() {
break;
case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid]
if (Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
if (Record[0] >= TypeList.size() || !TypeList[Record[0]])
- return Error("Invalid record");
+ return error("Invalid record");
CurTy = TypeList[Record[0]];
continue; // Skip the ValueList manipulation.
case bitc::CST_CODE_NULL: // NULL
@@ -1454,22 +2170,22 @@ std::error_code BitcodeReader::ParseConstants() {
break;
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
if (!CurTy->isIntegerTy() || Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
break;
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
if (!CurTy->isIntegerTy() || Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
- APInt VInt = ReadWideAPInt(Record,
- cast<IntegerType>(CurTy)->getBitWidth());
+ APInt VInt =
+ readWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth());
V = ConstantInt::get(Context, VInt);
break;
}
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
if (Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
if (CurTy->isHalfTy())
V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf,
APInt(16, (uint16_t)Record[0])));
@@ -1499,7 +2215,7 @@ std::error_code BitcodeReader::ParseConstants() {
case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
if (Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
unsigned Size = Record.size();
SmallVector<Constant*, 16> Elts;
@@ -1527,7 +2243,7 @@ std::error_code BitcodeReader::ParseConstants() {
case bitc::CST_CODE_STRING: // STRING: [values]
case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
if (Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
SmallString<16> Elts(Record.begin(), Record.end());
V = ConstantDataArray::getString(Context, Elts,
@@ -1536,7 +2252,7 @@ std::error_code BitcodeReader::ParseConstants() {
}
case bitc::CST_CODE_DATA: {// DATA: [n x value]
if (Record.empty())
- return Error("Invalid record");
+ return error("Invalid record");
Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
unsigned Size = Record.size();
@@ -1581,15 +2297,15 @@ std::error_code BitcodeReader::ParseConstants() {
else
V = ConstantDataArray::get(Context, Elts);
} else {
- return Error("Invalid type for value");
+ return error("Invalid type for value");
}
break;
}
case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval]
if (Record.size() < 3)
- return Error("Invalid record");
- int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
+ return error("Invalid record");
+ int Opc = getDecodedBinaryOpcode(Record[0], CurTy);
if (Opc < 0) {
V = UndefValue::get(CurTy); // Unknown binop.
} else {
@@ -1619,14 +2335,14 @@ std::error_code BitcodeReader::ParseConstants() {
}
case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
if (Record.size() < 3)
- return Error("Invalid record");
- int Opc = GetDecodedCastOpcode(Record[0]);
+ return error("Invalid record");
+ int Opc = getDecodedCastOpcode(Record[0]);
if (Opc < 0) {
V = UndefValue::get(CurTy); // Unknown cast.
} else {
Type *OpTy = getTypeByID(Record[1]);
if (!OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
V = UpgradeBitCastExpr(Opc, Op, CurTy);
if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy);
@@ -1635,24 +2351,34 @@ 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));
+ return error("Invalid record");
+ 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#]
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
Type *SelectorTy = Type::getInt1Ty(Context);
@@ -1671,22 +2397,22 @@ std::error_code BitcodeReader::ParseConstants() {
case bitc::CST_CODE_CE_EXTRACTELT
: { // CE_EXTRACTELT: [opty, opval, opty, opval]
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
VectorType *OpTy =
dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
if (!OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = nullptr;
if (Record.size() == 4) {
Type *IdxTy = getTypeByID(Record[2]);
if (!IdxTy)
- return Error("Invalid record");
+ return error("Invalid record");
Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy);
} else // TODO: Remove with llvm 4.0
Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
if (!Op1)
- return Error("Invalid record");
+ return error("Invalid record");
V = ConstantExpr::getExtractElement(Op0, Op1);
break;
}
@@ -1694,7 +2420,7 @@ std::error_code BitcodeReader::ParseConstants() {
: { // CE_INSERTELT: [opval, opval, opty, opval]
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
OpTy->getElementType());
@@ -1702,19 +2428,19 @@ std::error_code BitcodeReader::ParseConstants() {
if (Record.size() == 4) {
Type *IdxTy = getTypeByID(Record[2]);
if (!IdxTy)
- return Error("Invalid record");
+ return error("Invalid record");
Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy);
} else // TODO: Remove with llvm 4.0
Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
if (!Op2)
- return Error("Invalid record");
+ return error("Invalid record");
V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
break;
}
case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy);
Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
@@ -1728,7 +2454,7 @@ std::error_code BitcodeReader::ParseConstants() {
VectorType *OpTy =
dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
if (Record.size() < 4 || !RTy || !OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
@@ -1739,10 +2465,10 @@ std::error_code BitcodeReader::ParseConstants() {
}
case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred]
if (Record.size() < 4)
- return Error("Invalid record");
+ return error("Invalid record");
Type *OpTy = getTypeByID(Record[0]);
if (!OpTy)
- return Error("Invalid record");
+ return error("Invalid record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
@@ -1756,16 +2482,16 @@ std::error_code BitcodeReader::ParseConstants() {
// FIXME: Remove with the 4.0 release.
case bitc::CST_CODE_INLINEASM_OLD: {
if (Record.size() < 2)
- return Error("Invalid record");
+ return error("Invalid record");
std::string AsmStr, ConstrStr;
bool HasSideEffects = Record[0] & 1;
bool IsAlignStack = Record[0] >> 1;
unsigned AsmStrSize = Record[1];
if (2+AsmStrSize >= Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
unsigned ConstStrSize = Record[2+AsmStrSize];
if (3+AsmStrSize+ConstStrSize > Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
for (unsigned i = 0; i != AsmStrSize; ++i)
AsmStr += (char)Record[2+i];
@@ -1780,17 +2506,17 @@ std::error_code BitcodeReader::ParseConstants() {
// inteldialect).
case bitc::CST_CODE_INLINEASM: {
if (Record.size() < 2)
- return Error("Invalid record");
+ return error("Invalid record");
std::string AsmStr, ConstrStr;
bool HasSideEffects = Record[0] & 1;
bool IsAlignStack = (Record[0] >> 1) & 1;
unsigned AsmDialect = Record[0] >> 2;
unsigned AsmStrSize = Record[1];
if (2+AsmStrSize >= Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
unsigned ConstStrSize = Record[2+AsmStrSize];
if (3+AsmStrSize+ConstStrSize > Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
for (unsigned i = 0; i != AsmStrSize; ++i)
AsmStr += (char)Record[2+i];
@@ -1804,14 +2530,14 @@ std::error_code BitcodeReader::ParseConstants() {
}
case bitc::CST_CODE_BLOCKADDRESS:{
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
Type *FnTy = getTypeByID(Record[0]);
if (!FnTy)
- return Error("Invalid record");
+ return error("Invalid record");
Function *Fn =
dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
if (!Fn)
- return Error("Invalid record");
+ return error("Invalid record");
// Don't let Fn get dematerialized.
BlockAddressesTaken.insert(Fn);
@@ -1822,12 +2548,12 @@ std::error_code BitcodeReader::ParseConstants() {
unsigned BBID = Record[2];
if (!BBID)
// Invalid reference to entry block.
- return Error("Invalid ID");
+ return error("Invalid ID");
if (!Fn->empty()) {
Function::iterator BBI = Fn->begin(), BBE = Fn->end();
for (size_t I = 0, E = BBID; I != E; ++I) {
if (BBI == BBE)
- return Error("Invalid ID");
+ return error("Invalid ID");
++BBI;
}
BB = BBI;
@@ -1848,14 +2574,14 @@ std::error_code BitcodeReader::ParseConstants() {
}
}
- ValueList.AssignValue(V, NextCstNo);
+ ValueList.assignValue(V, NextCstNo);
++NextCstNo;
}
}
-std::error_code BitcodeReader::ParseUseLists() {
+std::error_code BitcodeReader::parseUseLists() {
if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
// Read all the records.
SmallVector<uint64_t, 64> Record;
@@ -1865,7 +2591,7 @@ std::error_code BitcodeReader::ParseUseLists() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
case BitstreamEntry::Record:
@@ -1886,7 +2612,7 @@ std::error_code BitcodeReader::ParseUseLists() {
unsigned RecordLength = Record.size();
if (RecordLength < 3)
// Records should have at least an ID and two indexes.
- return Error("Invalid record");
+ return error("Invalid record");
unsigned ID = Record.back();
Record.pop_back();
@@ -1917,13 +2643,38 @@ std::error_code BitcodeReader::ParseUseLists() {
}
}
-/// 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.
-std::error_code BitcodeReader::RememberAndSkipFunctionBody() {
+/// 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; }
+
+/// When we see the block for a function body, remember where it is and then
+/// skip it. This lets us lazily deserialize the functions.
+std::error_code BitcodeReader::rememberAndSkipFunctionBody() {
// Get the function we are talking about.
if (FunctionsWithBodies.empty())
- return Error("Insufficient function protos");
+ return error("Insufficient function protos");
Function *Fn = FunctionsWithBodies.back();
FunctionsWithBodies.pop_back();
@@ -1934,31 +2685,26 @@ std::error_code BitcodeReader::RememberAndSkipFunctionBody() {
// Skip over the function block for now.
if (Stream.SkipBlock())
- return Error("Invalid record");
+ return error("Invalid record");
return std::error_code();
}
-std::error_code BitcodeReader::GlobalCleanup() {
+std::error_code BitcodeReader::globalCleanup() {
// Patch the initializers for globals and aliases up.
- ResolveGlobalAndAliasInits();
+ resolveGlobalAndAliasInits();
if (!GlobalInits.empty() || !AliasInits.empty())
- return Error("Malformed global initializer set");
+ return error("Malformed global initializer set");
// Look for intrinsic functions which need to be upgraded at some point
- for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
- FI != FE; ++FI) {
+ for (Function &F : *TheModule) {
Function *NewFn;
- if (UpgradeIntrinsicFunction(FI, NewFn))
- UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
+ if (UpgradeIntrinsicFunction(&F, NewFn))
+ UpgradedIntrinsics.push_back(std::make_pair(&F, NewFn));
}
// Look for global variables which need to be renamed.
- for (Module::global_iterator
- GI = TheModule->global_begin(), GE = TheModule->global_end();
- GI != GE;) {
- GlobalVariable *GV = GI++;
- UpgradeGlobalVariable(GV);
- }
+ for (GlobalVariable &GV : TheModule->globals())
+ UpgradeGlobalVariable(&GV);
// Force deallocation of memory for these vectors to favor the client that
// want lazy deserialization.
@@ -1967,11 +2713,12 @@ 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))
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<uint64_t, 64> Record;
std::vector<std::string> SectionTable;
@@ -1983,45 +2730,51 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
switch (Entry.Kind) {
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
- return GlobalCleanup();
+ return globalCleanup();
case BitstreamEntry::SubBlock:
switch (Entry.ID) {
default: // Skip unknown content.
if (Stream.SkipBlock())
- return Error("Invalid record");
+ return error("Invalid record");
break;
case bitc::BLOCKINFO_BLOCK_ID:
if (Stream.ReadBlockInfoBlock())
- return Error("Malformed block");
+ return error("Malformed block");
break;
case bitc::PARAMATTR_BLOCK_ID:
- if (std::error_code EC = ParseAttributeBlock())
+ if (std::error_code EC = parseAttributeBlock())
return EC;
break;
case bitc::PARAMATTR_GROUP_BLOCK_ID:
- if (std::error_code EC = ParseAttributeGroupBlock())
+ if (std::error_code EC = parseAttributeGroupBlock())
return EC;
break;
case bitc::TYPE_BLOCK_ID_NEW:
- if (std::error_code EC = ParseTypeTable())
+ if (std::error_code EC = parseTypeTable())
return EC;
break;
case bitc::VALUE_SYMTAB_BLOCK_ID:
- if (std::error_code EC = ParseValueSymbolTable())
+ if (std::error_code EC = parseValueSymbolTable())
return EC;
SeenValueSymbolTable = true;
break;
case bitc::CONSTANTS_BLOCK_ID:
- if (std::error_code EC = ParseConstants())
+ if (std::error_code EC = parseConstants())
return EC;
- if (std::error_code EC = ResolveGlobalAndAliasInits())
+ if (std::error_code EC = resolveGlobalAndAliasInits())
return EC;
break;
case bitc::METADATA_BLOCK_ID:
- if (std::error_code EC = ParseMetadata())
+ 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;
case bitc::FUNCTION_BLOCK_ID:
@@ -2029,12 +2782,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
// FunctionsWithBodies list.
if (!SeenFirstFunctionBody) {
std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
- if (std::error_code EC = GlobalCleanup())
+ if (std::error_code EC = globalCleanup())
return EC;
SeenFirstFunctionBody = true;
}
- if (std::error_code EC = RememberAndSkipFunctionBody())
+ if (std::error_code EC = rememberAndSkipFunctionBody())
return EC;
// For streaming bitcode, suspend parsing when we reach the function
// bodies. Subsequent materialization calls will resume it when
@@ -2042,13 +2795,13 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
// the bitcode. If the bitcode file is old, the symbol table will be
// at the end instead and will not have been seen yet. In this case,
// just finish the parse now.
- if (LazyStreamer && SeenValueSymbolTable) {
+ if (IsStreamed && SeenValueSymbolTable) {
NextUnreadBit = Stream.GetCurrentBitNo();
return std::error_code();
}
break;
case bitc::USELIST_BLOCK_ID:
- if (std::error_code EC = ParseUseLists())
+ if (std::error_code EC = parseUseLists())
return EC;
break;
}
@@ -2065,12 +2818,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
if (Record.size() < 1)
- return Error("Invalid record");
+ return error("Invalid record");
// Only version #0 and #1 are supported so far.
unsigned module_version = Record[0];
switch (module_version) {
default:
- return Error("Invalid value");
+ return error("Invalid value");
case 0:
UseRelativeIDs = false;
break;
@@ -2082,50 +2835,50 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
}
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
TheModule->setTargetTriple(S);
break;
}
case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
TheModule->setDataLayout(S);
break;
}
case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
TheModule->setModuleInlineAsm(S);
break;
}
case bitc::MODULE_CODE_DEPLIB: { // DEPLIB: [strchr x N]
// FIXME: Remove in 4.0.
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
// Ignore value.
break;
}
case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
SectionTable.push_back(S);
break;
}
case bitc::MODULE_CODE_GCNAME: { // SECTIONNAME: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
GCTable.push_back(S);
break;
}
case bitc::MODULE_CODE_COMDAT: { // COMDAT: [selection_kind, name]
if (Record.size() < 2)
- return Error("Invalid record");
+ return error("Invalid record");
Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]);
unsigned ComdatNameSize = Record[1];
std::string ComdatName;
@@ -2139,36 +2892,46 @@ 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");
+ 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];
- GlobalValue::LinkageTypes Linkage = getDecodedLinkage(Record[3]);
- unsigned Alignment = (1 << Record[4]) >> 1;
+ return error("Invalid record");
+ 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();
+ }
+
+ 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())
- return Error("Invalid ID");
+ return error("Invalid ID");
Section = SectionTable[Record[5]-1];
}
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
// Local linkage must have default visibility.
if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage))
// FIXME: Change to an error if non-default in 4.0.
- Visibility = GetDecodedVisibility(Record[6]);
+ Visibility = getDecodedVisibility(Record[6]);
GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
if (Record.size() > 7)
- TLM = GetDecodedThreadLocalMode(Record[7]);
+ TLM = getDecodedThreadLocalMode(Record[7]);
bool UnnamedAddr = false;
if (Record.size() > 8)
@@ -2188,9 +2951,9 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
NewGV->setUnnamedAddr(UnnamedAddr);
if (Record.size() > 10)
- NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
+ NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10]));
else
- UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+ upgradeDLLImportExportLinkage(NewGV, RawLinkage);
ValueList.push_back(NewGV);
@@ -2198,11 +2961,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,
@@ -2210,38 +2977,41 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
// prologuedata, dllstorageclass, comdat, prefixdata]
case bitc::MODULE_CODE_FUNCTION: {
if (Record.size() < 8)
- return Error("Invalid record");
+ return error("Invalid record");
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());
+ return error("Invalid record");
+ if (auto *PTy = dyn_cast<PointerType>(Ty))
+ Ty = PTy->getElementType();
+ auto *FTy = dyn_cast<FunctionType>(Ty);
if (!FTy)
- return Error("Invalid type for value");
+ return error("Invalid type for value");
Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
"", TheModule);
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");
+ return error("Invalid ID");
Func->setSection(SectionTable[Record[6]-1]);
}
// Local linkage must have default visibility.
if (!Func->hasLocalLinkage())
// FIXME: Change to an error if non-default in 4.0.
- Func->setVisibility(GetDecodedVisibility(Record[7]));
+ Func->setVisibility(getDecodedVisibility(Record[7]));
if (Record.size() > 8 && Record[8]) {
- if (Record[8]-1 > GCTable.size())
- return Error("Invalid ID");
+ if (Record[8]-1 >= GCTable.size())
+ return error("Invalid ID");
Func->setGC(GCTable[Record[8]-1].c_str());
}
bool UnnamedAddr = false;
@@ -2252,19 +3022,26 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1));
if (Record.size() > 11)
- Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[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));
+ if (Record.size() > 14 && Record[14] != 0)
+ FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1));
+
ValueList.push_back(Func);
// If this is a function with a body, remember the prototype we are
@@ -2272,7 +3049,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
if (!isProto) {
Func->setIsMaterializable(true);
FunctionsWithBodies.push_back(Func);
- if (LazyStreamer)
+ if (IsStreamed)
DeferredFunctionInfo[Func] = 0;
}
break;
@@ -2281,28 +3058,27 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
// ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass]
case bitc::MODULE_CODE_ALIAS: {
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
Type *Ty = getTypeByID(Record[0]);
if (!Ty)
- return Error("Invalid record");
+ return error("Invalid record");
auto *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
- return Error("Invalid type for value");
+ 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())
// FIXME: Change to an error if non-default in 4.0.
- NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+ NewGA->setVisibility(getDecodedVisibility(Record[3]));
if (Record.size() > 4)
- NewGA->setDLLStorageClass(GetDecodedDLLStorageClass(Record[4]));
+ NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[4]));
else
- UpgradeDLLImportExportLinkage(NewGA, Record[2]);
+ upgradeDLLImportExportLinkage(NewGA, Record[2]);
if (Record.size() > 5)
- NewGA->setThreadLocalMode(GetDecodedThreadLocalMode(Record[5]));
+ NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[5]));
if (Record.size() > 6)
NewGA->setUnnamedAddr(Record[6]);
ValueList.push_back(NewGA);
@@ -2313,7 +3089,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
case bitc::MODULE_CODE_PURGEVALS:
// Trim down the value list to the specified size.
if (Record.size() < 1 || Record[0] > ValueList.size())
- return Error("Invalid record");
+ return error("Invalid record");
ValueList.shrinkTo(Record[0]);
break;
}
@@ -2321,10 +3097,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
}
}
-std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
- TheModule = nullptr;
+std::error_code
+BitcodeReader::parseBitcodeInto(std::unique_ptr<DataStreamer> Streamer,
+ Module *M, bool ShouldLazyLoadMetadata) {
+ TheModule = M;
- if (std::error_code EC = InitStream())
+ if (std::error_code EC = initStream(std::move(Streamer)))
return EC;
// Sniff for the signature.
@@ -2334,64 +3112,33 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
Stream.Read(4) != 0xC ||
Stream.Read(4) != 0xE ||
Stream.Read(4) != 0xD)
- return Error("Invalid bitcode signature");
+ return error("Invalid bitcode signature");
// 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()) {
+ // We didn't really read a proper Module.
+ return error("Malformed IR file");
+ }
BitstreamEntry Entry =
Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
- switch (Entry.Kind) {
- case BitstreamEntry::Error:
- return Error("Malformed block");
- case BitstreamEntry::EndBlock:
- return std::error_code();
-
- case BitstreamEntry::SubBlock:
- switch (Entry.ID) {
- case bitc::BLOCKINFO_BLOCK_ID:
- if (Stream.ReadBlockInfoBlock())
- return Error("Malformed block");
- break;
- case bitc::MODULE_BLOCK_ID:
- // Reject multiple MODULE_BLOCK's in a single bitstream.
- if (TheModule)
- return Error("Invalid multiple blocks");
- TheModule = M;
- if (std::error_code EC = ParseModule(false))
- return EC;
- if (LazyStreamer)
- return std::error_code();
- break;
- default:
- if (Stream.SkipBlock())
- return Error("Invalid record");
- break;
- }
- continue;
- case BitstreamEntry::Record:
- // There should be no records in the top-level of blocks.
+ if (Entry.Kind != BitstreamEntry::SubBlock)
+ return error("Malformed block");
- // The ranlib in Xcode 4 will align archive members by appending newlines
- // to the end of them. If this file size is a multiple of 4 but not 8, we
- // have to read and ignore these final 4 bytes :-(
- if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 &&
- Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
- Stream.AtEndOfStream())
- return std::error_code();
+ if (Entry.ID == bitc::MODULE_BLOCK_ID)
+ return parseModule(false, ShouldLazyLoadMetadata);
- return Error("Invalid record");
- }
+ if (Stream.SkipBlock())
+ return error("Invalid record");
}
}
ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<uint64_t, 64> Record;
@@ -2403,7 +3150,7 @@ ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return Triple;
case BitstreamEntry::Record:
@@ -2416,8 +3163,8 @@ ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
default: break; // Default behavior, ignore unknown content.
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S;
- if (ConvertToString(Record, 0, S))
- return Error("Invalid record");
+ if (convertToString(Record, 0, S))
+ return error("Invalid record");
Triple = S;
break;
}
@@ -2428,7 +3175,7 @@ ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
}
ErrorOr<std::string> BitcodeReader::parseTriple() {
- if (std::error_code EC = InitStream())
+ if (std::error_code EC = initStream(nullptr))
return EC;
// Sniff for the signature.
@@ -2438,7 +3185,7 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
Stream.Read(4) != 0xC ||
Stream.Read(4) != 0xE ||
Stream.Read(4) != 0xD)
- return Error("Invalid bitcode signature");
+ return error("Invalid bitcode signature");
// We expect a number of well-defined blocks, though we don't necessarily
// need to understand them all.
@@ -2447,7 +3194,7 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
switch (Entry.Kind) {
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
@@ -2457,7 +3204,7 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
// Ignore other sub-blocks.
if (Stream.SkipBlock())
- return Error("Malformed block");
+ return error("Malformed block");
continue;
case BitstreamEntry::Record:
@@ -2467,10 +3214,10 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
}
}
-/// ParseMetadataAttachment - Parse metadata attachments.
-std::error_code BitcodeReader::ParseMetadataAttachment() {
+/// Parse metadata attachments.
+std::error_code BitcodeReader::parseMetadataAttachment(Function &F) {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
- return Error("Invalid record");
+ return error("Invalid record");
SmallVector<uint64_t, 64> Record;
while (1) {
@@ -2479,7 +3226,7 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
return std::error_code();
case BitstreamEntry::Record:
@@ -2494,15 +3241,28 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
break;
case bitc::METADATA_ATTACHMENT: {
unsigned RecordLength = Record.size();
- if (Record.empty() || (RecordLength - 1) % 2 == 1)
- return Error("Invalid record");
+ 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];
DenseMap<unsigned, unsigned>::iterator I =
MDKindMap.find(Kind);
if (I == MDKindMap.end())
- return Error("Invalid ID");
+ return error("Invalid ID");
Metadata *Node = MDValueList.getValueFwdRef(Record[i + 1]);
if (isa<LocalAsMetadata>(Node))
// Drop the attachment. This used to be legal, but there's no
@@ -2518,10 +3278,24 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
}
}
-/// ParseFunctionBody - Lazily parse the specified function body block.
-std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
+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();
+}
+
+/// Lazily parse the specified function body block.
+std::error_code BitcodeReader::parseFunctionBody(Function *F) {
if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
- return Error("Invalid record");
+ return error("Invalid record");
InstructionList.clear();
unsigned ModuleValueListSize = ValueList.size();
@@ -2552,7 +3326,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
switch (Entry.Kind) {
case BitstreamEntry::Error:
- return Error("Malformed block");
+ return error("Malformed block");
case BitstreamEntry::EndBlock:
goto OutOfRecordLoop;
@@ -2560,27 +3334,27 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
switch (Entry.ID) {
default: // Skip unknown content.
if (Stream.SkipBlock())
- return Error("Invalid record");
+ return error("Invalid record");
break;
case bitc::CONSTANTS_BLOCK_ID:
- if (std::error_code EC = ParseConstants())
+ if (std::error_code EC = parseConstants())
return EC;
NextValueNo = ValueList.size();
break;
case bitc::VALUE_SYMTAB_BLOCK_ID:
- if (std::error_code EC = ParseValueSymbolTable())
+ if (std::error_code EC = parseValueSymbolTable())
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:
- if (std::error_code EC = ParseMetadata())
+ if (std::error_code EC = parseMetadata())
return EC;
break;
case bitc::USELIST_BLOCK_ID:
- if (std::error_code EC = ParseUseLists())
+ if (std::error_code EC = parseUseLists())
return EC;
break;
}
@@ -2597,10 +3371,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned BitCode = Stream.readRecord(Entry.ID, Record);
switch (BitCode) {
default: // Default behavior: reject
- return Error("Invalid value");
+ return error("Invalid value");
case bitc::FUNC_CODE_DECLAREBLOCKS: { // DECLAREBLOCKS: [nblocks]
if (Record.size() < 1 || Record[0] == 0)
- return Error("Invalid record");
+ return error("Invalid record");
// Create all the basic blocks for the function.
FunctionBBs.resize(Record[0]);
@@ -2613,7 +3387,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
auto &BBRefs = BBFRI->second;
// Check for invalid basic block references.
if (BBRefs.size() > FunctionBBs.size())
- return Error("Invalid ID");
+ return error("Invalid ID");
assert(!BBRefs.empty() && "Unexpected empty array");
assert(!BBRefs.front() && "Invalid reference to entry block");
for (unsigned I = 0, E = FunctionBBs.size(), RE = BBRefs.size(); I != E;
@@ -2639,7 +3413,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
I = getLastInstruction();
if (!I)
- return Error("Invalid record");
+ return error("Invalid record");
I->setDebugLoc(LastLoc);
I = nullptr;
continue;
@@ -2647,7 +3421,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
I = getLastInstruction();
if (!I || Record.size() < 4)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned Line = Record[0], Col = Record[1];
unsigned ScopeID = Record[2], IAID = Record[3];
@@ -2667,11 +3441,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
OpNum+1 > Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
- int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
+ int Opc = getDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
if (Opc == -1)
- return Error("Invalid record");
+ return error("Invalid record");
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
InstructionList.push_back(I);
if (OpNum < Record.size()) {
@@ -2713,12 +3487,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
OpNum+2 != Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
Type *ResTy = getTypeByID(Record[OpNum]);
- int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
+ int Opc = getDecodedCastOpcode(Record[OpNum + 1]);
if (Opc == -1 || !ResTy)
- return Error("Invalid record");
+ return error("Invalid record");
Instruction *Temp = nullptr;
if ((I = UpgradeBitCastInst(Opc, Op, ResTy, Temp))) {
if (Temp) {
@@ -2731,24 +3505,47 @@ 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");
+ 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;
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
- return Error("Invalid record");
+ return error("Invalid record");
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;
}
@@ -2758,15 +3555,33 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Agg;
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
- return Error("Invalid record");
+ 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");
+ 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);
@@ -2779,20 +3594,41 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Agg;
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
- return Error("Invalid record");
+ return error("Invalid record");
Value *Val;
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
- return Error("Invalid record");
+ 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");
+ 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;
@@ -2806,7 +3642,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond))
- return Error("Invalid record");
+ return error("Invalid record");
I = SelectInst::Create(Cond, TrueVal, FalseVal);
InstructionList.push_back(I);
@@ -2821,18 +3657,18 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
getValueTypePair(Record, OpNum, NextValueNo, Cond))
- return Error("Invalid record");
+ return error("Invalid record");
// select condition can be either i1 or [N x i1]
if (VectorType* vector_type =
dyn_cast<VectorType>(Cond->getType())) {
// expect <n x i1>
if (vector_type->getElementType() != Type::getInt1Ty(Context))
- return Error("Invalid type for value");
+ return error("Invalid type for value");
} else {
// expect i1
if (Cond->getType() != Type::getInt1Ty(Context))
- return Error("Invalid type for value");
+ return error("Invalid type for value");
}
I = SelectInst::Create(Cond, TrueVal, FalseVal);
@@ -2845,7 +3681,9 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Value *Vec, *Idx;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
getValueTypePair(Record, OpNum, NextValueNo, Idx))
- return Error("Invalid record");
+ 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,11 +3692,14 @@ 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");
+ return error("Invalid record");
I = InsertElementInst::Create(Vec, Elt, Idx);
InstructionList.push_back(I);
break;
@@ -2869,10 +3710,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Value *Vec1, *Vec2, *Mask;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2))
- return Error("Invalid record");
+ return error("Invalid record");
if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
- return Error("Invalid record");
+ 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;
@@ -2890,7 +3733,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
OpNum+1 != Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
if (LHS->getType()->isFPOrFPVectorTy())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
@@ -2912,9 +3755,9 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op = nullptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
- return Error("Invalid record");
+ return error("Invalid record");
if (OpNum != Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
I = ReturnInst::Create(Context, Op);
InstructionList.push_back(I);
@@ -2922,10 +3765,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
if (Record.size() != 1 && Record.size() != 3)
- return Error("Invalid record");
+ return error("Invalid record");
BasicBlock *TrueDest = getBasicBlock(Record[0]);
if (!TrueDest)
- return Error("Invalid record");
+ return error("Invalid record");
if (Record.size() == 1) {
I = BranchInst::Create(TrueDest);
@@ -2936,7 +3779,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Value *Cond = getValue(Record, 2, NextValueNo,
Type::getInt1Ty(Context));
if (!FalseDest || !Cond)
- return Error("Invalid record");
+ return error("Invalid record");
I = BranchInst::Create(TrueDest, FalseDest, Cond);
InstructionList.push_back(I);
}
@@ -2956,7 +3799,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Value *Cond = getValue(Record, 2, NextValueNo, OpTy);
BasicBlock *Default = getBasicBlock(Record[3]);
if (!OpTy || !Cond || !Default)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned NumCases = Record[4];
@@ -2974,7 +3817,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned ActiveWords = 1;
if (ValueBitWidth > 64)
ActiveWords = Record[CurIdx++];
- Low = ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
+ Low = readWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
ValueBitWidth);
CurIdx += ActiveWords;
@@ -2982,9 +3825,8 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
ActiveWords = 1;
if (ValueBitWidth > 64)
ActiveWords = Record[CurIdx++];
- APInt High =
- ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
- ValueBitWidth);
+ APInt High = readWideAPInt(
+ makeArrayRef(&Record[CurIdx], ActiveWords), ValueBitWidth);
CurIdx += ActiveWords;
// FIXME: It is not clear whether values in the range should be
@@ -3008,12 +3850,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
// Old SwitchInst format without case ranges.
if (Record.size() < 3 || (Record.size() & 1) == 0)
- return Error("Invalid record");
+ return error("Invalid record");
Type *OpTy = getTypeByID(Record[0]);
Value *Cond = getValue(Record, 1, NextValueNo, OpTy);
BasicBlock *Default = getBasicBlock(Record[2]);
if (!OpTy || !Cond || !Default)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned NumCases = (Record.size()-3)/2;
SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
InstructionList.push_back(SI);
@@ -3023,7 +3865,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
if (!CaseVal || !DestBB) {
delete SI;
- return Error("Invalid record");
+ return error("Invalid record");
}
SI->addCase(CaseVal, DestBB);
}
@@ -3032,11 +3874,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...]
if (Record.size() < 2)
- return Error("Invalid record");
+ return error("Invalid record");
Type *OpTy = getTypeByID(Record[0]);
Value *Address = getValue(Record, 1, NextValueNo, OpTy);
if (!OpTy || !Address)
- return Error("Invalid record");
+ return error("Invalid record");
unsigned NumDests = Record.size()-2;
IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests);
InstructionList.push_back(IBI);
@@ -3045,7 +3887,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
IBI->addDestination(DestBB);
} else {
delete IBI;
- return Error("Invalid record");
+ return error("Invalid record");
}
}
I = IBI;
@@ -3055,51 +3897,60 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_INVOKE: {
// 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]);
+ return error("Invalid record");
+ 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");
+ 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) {
Ops.push_back(getValue(Record, OpNum, NextValueNo,
FTy->getParamType(i)));
if (!Ops.back())
- return Error("Invalid record");
+ return error("Invalid record");
}
if (!FTy->isVarArg()) {
if (Record.size() != OpNum)
- return Error("Invalid record");
+ return error("Invalid record");
} else {
// Read type/value pairs for varargs params.
while (OpNum != Record.size()) {
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
- return Error("Invalid record");
+ return error("Invalid record");
Ops.push_back(Op);
}
}
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;
}
@@ -3107,7 +3958,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned Idx = 0;
Value *Val = nullptr;
if (getValueTypePair(Record, Idx, NextValueNo, Val))
- return Error("Invalid record");
+ return error("Invalid record");
I = ResumeInst::Create(Val);
InstructionList.push_back(I);
break;
@@ -3118,10 +3969,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
break;
case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
if (Record.size() < 1 || ((Record.size()-1)&1))
- return Error("Invalid record");
+ return error("Invalid record");
Type *Ty = getTypeByID(Record[0]);
if (!Ty)
- return Error("Invalid record");
+ return error("Invalid record");
PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
InstructionList.push_back(PN);
@@ -3137,28 +3988,42 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
V = getValue(Record, 1+i, NextValueNo, Ty);
BasicBlock *BB = getBasicBlock(Record[2+i]);
if (!V || !BB)
- return Error("Invalid record");
+ return error("Invalid record");
PN->addIncoming(V, BB);
}
I = PN;
break;
}
- case bitc::FUNC_CODE_INST_LANDINGPAD: {
+ case bitc::FUNC_CODE_INST_LANDINGPAD:
+ case bitc::FUNC_CODE_INST_LANDINGPAD_OLD: {
// LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?]
unsigned Idx = 0;
- if (Record.size() < 4)
- return Error("Invalid record");
+ if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD) {
+ if (Record.size() < 3)
+ return error("Invalid record");
+ } else {
+ assert(BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD);
+ if (Record.size() < 4)
+ return error("Invalid record");
+ }
Type *Ty = getTypeByID(Record[Idx++]);
if (!Ty)
- return Error("Invalid record");
- Value *PersFn = nullptr;
- if (getValueTypePair(Record, Idx, NextValueNo, PersFn))
- return Error("Invalid record");
+ return error("Invalid record");
+ if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) {
+ Value *PersFn = nullptr;
+ if (getValueTypePair(Record, Idx, NextValueNo, PersFn))
+ return error("Invalid record");
+
+ if (!F->hasPersonalityFn())
+ F->setPersonalityFn(cast<Constant>(PersFn));
+ else if (F->getPersonalityFn() != cast<Constant>(PersFn))
+ return error("Personality function mismatch");
+ }
bool IsCleanup = !!Record[Idx++];
unsigned NumClauses = Record[Idx++];
- LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses);
+ LandingPadInst *LP = LandingPadInst::Create(Ty, NumClauses);
LP->setCleanup(IsCleanup);
for (unsigned J = 0; J != NumClauses; ++J) {
LandingPadInst::ClauseType CT =
@@ -3167,7 +4032,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, Idx, NextValueNo, Val)) {
delete LP;
- return Error("Invalid record");
+ return error("Invalid record");
}
assert((CT != LandingPadInst::Catch ||
@@ -3186,17 +4051,29 @@ 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]));
+ return error("Invalid record");
+ 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);
+ return error("Invalid record");
+ AllocaInst *AI = new AllocaInst(Ty, Size, Align);
AI->setUsedWithInAlloca(InAlloca);
I = AI;
InstructionList.push_back(I);
@@ -3206,10 +4083,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
- OpNum+2 != Record.size())
- return Error("Invalid record");
+ (OpNum + 2 != Record.size() && OpNum + 3 != Record.size()))
+ return error("Invalid record");
+
+ 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);
- I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
InstructionList.push_back(I);
break;
}
@@ -3218,81 +4108,118 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
- OpNum+4 != Record.size())
- return Error("Invalid record");
+ (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]);
+ AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]);
if (Ordering == NotAtomic || Ordering == Release ||
Ordering == AcquireRelease)
- return Error("Invalid record");
+ return error("Invalid record");
if (Ordering != NotAtomic && Record[OpNum] == 0)
- return Error("Invalid record");
- SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+ return error("Invalid record");
+ SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]);
+
+ unsigned Align;
+ if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align))
+ return EC;
+ I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope);
- I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1,
- 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())
- return Error("Invalid record");
-
- I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ (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");
+
+ 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())
- return Error("Invalid record");
-
- AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+ (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)
- return Error("Invalid record");
- SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+ return error("Invalid record");
+ SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]);
if (Ordering != NotAtomic && Record[OpNum] == 0)
- return Error("Invalid record");
+ 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))
- return Error("Invalid record");
- AtomicOrdering SuccessOrdering = GetDecodedOrdering(Record[OpNum+1]);
+ (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]);
+ 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 =
AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering);
else
- FailureOrdering = GetDecodedOrdering(Record[OpNum+3]);
+ FailureOrdering = getDecodedOrdering(Record[OpNum + 3]);
I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering,
SynchScope);
@@ -3319,15 +4246,15 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
OpNum+4 != Record.size())
- return Error("Invalid record");
- AtomicRMWInst::BinOp Operation = GetDecodedRMWOperation(Record[OpNum]);
+ return error("Invalid record");
+ AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]);
if (Operation < AtomicRMWInst::FIRST_BINOP ||
Operation > AtomicRMWInst::LAST_BINOP)
- return Error("Invalid record");
- AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+ return error("Invalid record");
+ AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]);
if (Ordering == NotAtomic || Ordering == Unordered)
- return Error("Invalid record");
- SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+ return error("Invalid record");
+ SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]);
I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope);
cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]);
InstructionList.push_back(I);
@@ -3335,12 +4262,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope]
if (2 != Record.size())
- return Error("Invalid record");
- AtomicOrdering Ordering = GetDecodedOrdering(Record[0]);
+ return error("Invalid record");
+ AtomicOrdering Ordering = getDecodedOrdering(Record[0]);
if (Ordering == NotAtomic || Ordering == Unordered ||
Ordering == Monotonic)
- return Error("Invalid record");
- SynchronizationScope SynchScope = GetDecodedSynchScope(Record[1]);
+ return error("Invalid record");
+ SynchronizationScope SynchScope = getDecodedSynchScope(Record[1]);
I = new FenceInst(Context, Ordering, SynchScope);
InstructionList.push_back(I);
break;
@@ -3348,21 +4275,33 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_CALL: {
// CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...]
if (Record.size() < 3)
- return Error("Invalid record");
+ 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");
+ 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.
@@ -3373,23 +4312,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
Args.push_back(getValue(Record, OpNum, NextValueNo,
FTy->getParamType(i)));
if (!Args.back())
- return Error("Invalid record");
+ return error("Invalid record");
}
// Read type/value pairs for varargs params.
if (!FTy->isVarArg()) {
if (OpNum != Record.size())
- return Error("Invalid record");
+ return error("Invalid record");
} else {
while (OpNum != Record.size()) {
Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
- return Error("Invalid record");
+ return error("Invalid record");
Args.push_back(Op);
}
}
- 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));
@@ -3404,12 +4343,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty]
if (Record.size() < 3)
- return Error("Invalid record");
+ return error("Invalid record");
Type *OpTy = getTypeByID(Record[0]);
Value *Op = getValue(Record, 1, NextValueNo, OpTy);
Type *ResTy = getTypeByID(Record[2]);
if (!OpTy || !Op || !ResTy)
- return Error("Invalid record");
+ return error("Invalid record");
I = new VAArgInst(Op, ResTy);
InstructionList.push_back(I);
break;
@@ -3420,7 +4359,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
// this file.
if (!CurBB) {
delete I;
- return Error("Invalid instruction with no BB");
+ return error("Invalid instruction with no BB");
}
CurBB->getInstList().push_back(I);
@@ -3432,7 +4371,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
// Non-void values get registered in the value table for future use.
if (I && !I->getType()->isVoidTy())
- ValueList.AssignValue(I, NextValueNo++);
+ ValueList.assignValue(I, NextValueNo++);
}
OutOfRecordLoop:
@@ -3447,7 +4386,7 @@ OutOfRecordLoop:
delete A;
}
}
- return Error("Never resolved value found in function");
+ return error("Never resolved value found in function");
}
}
@@ -3462,15 +4401,15 @@ OutOfRecordLoop:
}
/// Find the function body in the bitcode stream
-std::error_code BitcodeReader::FindFunctionInStream(
+std::error_code BitcodeReader::findFunctionInStream(
Function *F,
DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator) {
while (DeferredFunctionInfoIterator->second == 0) {
if (Stream.AtEndOfStream())
- return Error("Could not find function in stream");
+ return error("Could not find function in stream");
// ParseModule will parse the next body in the stream and set its
// position in the DeferredFunctionInfo map.
- if (std::error_code EC = ParseModule(true))
+ if (std::error_code EC = parseModule(true))
return EC;
}
return std::error_code();
@@ -3483,6 +4422,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())
@@ -3492,17 +4434,20 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) {
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
// If its position is recorded as 0, its body is somewhere in the stream
// but we haven't seen it yet.
- if (DFII->second == 0 && LazyStreamer)
- if (std::error_code EC = FindFunctionInStream(F, DFII))
+ if (DFII->second == 0 && IsStreamed)
+ if (std::error_code EC = findFunctionInStream(F, DFII))
return EC;
// Move the bit stream to the saved position of the deferred function body.
Stream.JumpToBit(DFII->second);
- if (std::error_code EC = ParseFunctionBody(F))
+ if (std::error_code EC = parseFunctionBody(F))
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 +4478,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 +4491,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;
@@ -3564,12 +4512,12 @@ std::error_code BitcodeReader::MaterializeModule(Module *M) {
// pointing to the END_BLOCK record after them. Now make sure the rest
// of the bits in the module have been read.
if (NextUnreadBit)
- ParseModule(true);
+ parseModule(true);
// Check that all block address forward references got resolved (as we
// promised above).
if (!BasicBlockFwdRefs.empty())
- return Error("Never resolved function from blockaddress");
+ return error("Never resolved function from blockaddress");
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
@@ -3601,24 +4549,25 @@ std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const {
return IdentifiedStructTypes;
}
-std::error_code BitcodeReader::InitStream() {
- if (LazyStreamer)
- return InitLazyStream();
- return InitStreamFromBuffer();
+std::error_code
+BitcodeReader::initStream(std::unique_ptr<DataStreamer> Streamer) {
+ if (Streamer)
+ return initLazyStream(std::move(Streamer));
+ return initStreamFromBuffer();
}
-std::error_code BitcodeReader::InitStreamFromBuffer() {
+std::error_code BitcodeReader::initStreamFromBuffer() {
const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
if (Buffer->getBufferSize() & 3)
- return Error("Invalid bitcode signature");
+ return error("Invalid bitcode signature");
// If we have a wrapper header, parse it and ignore the non-bc file contents.
// The magic number is 0x0B17C0DE stored in little endian.
if (isBitcodeWrapper(BufPtr, BufEnd))
if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
- return Error("Invalid bitcode wrapper header");
+ return error("Invalid bitcode wrapper header");
StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
Stream.init(&*StreamFile);
@@ -3626,20 +4575,22 @@ std::error_code BitcodeReader::InitStreamFromBuffer() {
return std::error_code();
}
-std::error_code BitcodeReader::InitLazyStream() {
+std::error_code
+BitcodeReader::initLazyStream(std::unique_ptr<DataStreamer> Streamer) {
// Check and strip off the bitcode wrapper; BitstreamReader expects never to
// see it.
- auto OwnedBytes = llvm::make_unique<StreamingMemoryObject>(LazyStreamer);
+ auto OwnedBytes =
+ llvm::make_unique<StreamingMemoryObject>(std::move(Streamer));
StreamingMemoryObject &Bytes = *OwnedBytes;
StreamFile = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
Stream.init(&*StreamFile);
unsigned char buf[16];
if (Bytes.readBytes(buf, 16, 0) != 16)
- return Error("Invalid bitcode signature");
+ return error("Invalid bitcode signature");
if (!isBitcode(buf, buf + 16))
- return Error("Invalid bitcode signature");
+ return error("Invalid bitcode signature");
if (isBitcodeWrapper(buf, buf + 4)) {
const unsigned char *bitcodeStart = buf;
@@ -3667,7 +4618,7 @@ class BitcodeErrorCategoryType : public std::error_category {
llvm_unreachable("Unknown error type!");
}
};
-}
+} // namespace
static ManagedStatic<BitcodeErrorCategoryType> ErrorCategory;
@@ -3679,80 +4630,86 @@ const std::error_category &llvm::BitcodeErrorCategory() {
// External interface
//===----------------------------------------------------------------------===//
-/// \brief Get a lazy one-at-time loading module from bitcode.
-///
-/// This isn't always used in a lazy context. In particular, it's also used by
-/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
-/// in forward-referenced functions from block address references.
-///
-/// \param[in] WillMaterializeAll Set to \c true if the caller promises to
-/// materialize everything -- in particular, if this isn't truly lazy.
-static ErrorOr<Module *>
-getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context, bool WillMaterializeAll,
- DiagnosticHandlerFunction DiagnosticHandler) {
- Module *M = new Module(Buffer->getBufferIdentifier(), Context);
- BitcodeReader *R =
- new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+static ErrorOr<std::unique_ptr<Module>>
+getBitcodeModuleImpl(std::unique_ptr<DataStreamer> Streamer, StringRef Name,
+ BitcodeReader *R, LLVMContext &Context,
+ bool MaterializeAll, bool ShouldLazyLoadMetadata) {
+ std::unique_ptr<Module> M = make_unique<Module>(Name, Context);
M->setMaterializer(R);
auto cleanupOnError = [&](std::error_code EC) {
R->releaseBuffer(); // Never take ownership on error.
- delete M; // Also deletes R.
return EC;
};
- if (std::error_code EC = R->ParseBitcodeInto(M))
+ // Delay parsing Metadata if ShouldLazyLoadMetadata is true.
+ if (std::error_code EC = R->parseBitcodeInto(std::move(Streamer), M.get(),
+ ShouldLazyLoadMetadata))
return cleanupOnError(EC);
- if (!WillMaterializeAll)
+ if (MaterializeAll) {
+ // Read in the entire module, and destroy the BitcodeReader.
+ if (std::error_code EC = M->materializeAllPermanently())
+ return cleanupOnError(EC);
+ } else {
// Resolve forward references from blockaddresses.
if (std::error_code EC = R->materializeForwardReferencedFunctions())
return cleanupOnError(EC);
+ }
+ return std::move(M);
+}
+
+/// \brief Get a lazy one-at-time loading module from bitcode.
+///
+/// This isn't always used in a lazy context. In particular, it's also used by
+/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
+/// in forward-referenced functions from block address references.
+///
+/// \param[in] MaterializeAll Set to \c true if we should materialize
+/// everything.
+static ErrorOr<std::unique_ptr<Module>>
+getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
+ LLVMContext &Context, bool MaterializeAll,
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata = false) {
+ BitcodeReader *R =
+ new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+
+ ErrorOr<std::unique_ptr<Module>> Ret =
+ getBitcodeModuleImpl(nullptr, Buffer->getBufferIdentifier(), R, Context,
+ MaterializeAll, ShouldLazyLoadMetadata);
+ if (!Ret)
+ return Ret;
Buffer.release(); // The BitcodeReader owns it now.
- return M;
+ return Ret;
}
-ErrorOr<Module *>
-llvm::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
- LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ErrorOr<std::unique_ptr<Module>> llvm::getLazyBitcodeModule(
+ std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context,
+ DiagnosticHandlerFunction DiagnosticHandler, bool ShouldLazyLoadMetadata) {
return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
- DiagnosticHandler);
+ DiagnosticHandler, ShouldLazyLoadMetadata);
}
-ErrorOr<std::unique_ptr<Module>>
-llvm::getStreamedBitcodeModule(StringRef Name, DataStreamer *Streamer,
- LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ErrorOr<std::unique_ptr<Module>> llvm::getStreamedBitcodeModule(
+ StringRef Name, std::unique_ptr<DataStreamer> Streamer,
+ LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler) {
std::unique_ptr<Module> M = make_unique<Module>(Name, Context);
- BitcodeReader *R = new BitcodeReader(Streamer, Context, DiagnosticHandler);
- M->setMaterializer(R);
- if (std::error_code EC = R->ParseBitcodeInto(M.get()))
- return EC;
- return std::move(M);
+ BitcodeReader *R = new BitcodeReader(Context, DiagnosticHandler);
+
+ return getBitcodeModuleImpl(std::move(Streamer), Name, R, Context, false,
+ false);
}
-ErrorOr<Module *>
+ErrorOr<std::unique_ptr<Module>>
llvm::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
DiagnosticHandlerFunction DiagnosticHandler) {
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
- ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModuleImpl(
- std::move(Buf), Context, true, DiagnosticHandler);
- if (!ModuleOrErr)
- return ModuleOrErr;
- Module *M = ModuleOrErr.get();
- // Read in the entire module, and destroy the BitcodeReader.
- if (std::error_code EC = M->materializeAllPermanently()) {
- delete M;
- return EC;
- }
-
+ return getLazyBitcodeModuleImpl(std::move(Buf), Context, true,
+ DiagnosticHandler);
// TODO: Restore the use-lists to the in-memory state when the bitcode was
// written. We must defer until the Module has been fully materialized.
-
- return M;
}
std::string
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h
deleted file mode 100644
index 5090be4..0000000
--- a/contrib/llvm/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/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp
index 5e3232e..a103fbd 100644
--- a/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp
+++ b/contrib/llvm/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/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a96e866..e79eeb0 100644
--- a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/contrib/llvm/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:
@@ -226,6 +232,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_STACK_PROTECT_REQ;
case Attribute::StackProtectStrong:
return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
+ case Attribute::SafeStack:
+ return bitc::ATTR_KIND_SAFESTACK;
case Attribute::StructRet:
return bitc::ATTR_KIND_STRUCT_RET;
case Attribute::SanitizeAddress:
@@ -322,7 +330,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 +488,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 +502,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 +557,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 +594,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 +635,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 +663,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));
@@ -682,8 +695,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
for (const Function &F : *M) {
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
// section, visibility, gc, unnamed_addr, prologuedata,
- // dllstorageclass, comdat, prefixdata]
- Vals.push_back(VE.getTypeID(F.getType()));
+ // dllstorageclass, comdat, prefixdata, personalityfn]
+ Vals.push_back(VE.getTypeID(F.getFunctionType()));
Vals.push_back(F.getCallingConv());
Vals.push_back(F.isDeclaration());
Vals.push_back(getEncodedLinkage(F));
@@ -699,6 +712,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0);
Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1)
: 0);
+ Vals.push_back(
+ F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0);
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
@@ -760,26 +775,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 +798,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 +1166,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 +1182,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 +1213,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 +1287,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 +1413,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 +1542,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 +1699,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 +1721,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 +1807,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.
@@ -1477,7 +1861,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
const LandingPadInst &LP = cast<LandingPadInst>(I);
Code = bitc::FUNC_CODE_INST_LANDINGPAD;
Vals.push_back(VE.getTypeID(LP.getType()));
- PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE);
Vals.push_back(LP.isCleanup());
Vals.push_back(LP.getNumClauses());
for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
@@ -1492,15 +1875,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 +1898,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 +1912,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 +1923,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 +1952,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 +2058,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 +2108,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 +2125,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 +2150,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 +2211,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 +2231,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 +2252,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 +2286,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 +2315,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 +2342,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 +2375,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.
@@ -2007,10 +2406,7 @@ enum {
static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
uint32_t &Position) {
- Buffer[Position + 0] = (unsigned char) (Value >> 0);
- Buffer[Position + 1] = (unsigned char) (Value >> 8);
- Buffer[Position + 2] = (unsigned char) (Value >> 16);
- Buffer[Position + 3] = (unsigned char) (Value >> 24);
+ support::endian::write32le(&Buffer[Position], Value);
Position += 4;
}
@@ -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/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index 25456a4..c890380 100644
--- a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -19,29 +19,33 @@
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;
}
};
-}
+} // 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/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index 27a63d8..53c3a40 100644
--- a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/contrib/llvm/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"
@@ -51,7 +52,7 @@ struct OrderMap {
IDs[V].first = ID;
}
};
-}
+} // namespace
static void orderValue(const Value *V, OrderMap &OM) {
if (OM.lookup(V).first)
@@ -92,6 +93,9 @@ static OrderMap orderModule(const Module &M) {
if (F.hasPrologueData())
if (!isa<GlobalValue>(F.getPrologueData()))
orderValue(F.getPrologueData(), OM);
+ if (F.hasPersonalityFn())
+ if (!isa<GlobalValue>(F.getPersonalityFn()))
+ orderValue(F.getPersonalityFn(), OM);
}
OM.LastGlobalConstantID = OM.size();
@@ -273,6 +277,8 @@ static UseListOrderStack predictUseListOrder(const Module &M) {
predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack);
if (F.hasPrologueData())
predictValueUseListOrder(F.getPrologueData(), nullptr, OM, Stack);
+ if (F.hasPersonalityFn())
+ predictValueUseListOrder(F.getPersonalityFn(), nullptr, OM, Stack);
}
return Stack;
@@ -282,50 +288,53 @@ 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.
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- EnumerateValue(I);
+ for (const GlobalVariable &GV : M.globals())
+ EnumerateValue(&GV);
// Enumerate the functions.
- for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
- EnumerateValue(I);
- EnumerateAttributes(cast<Function>(I)->getAttributes());
+ for (const Function & F : M) {
+ EnumerateValue(&F);
+ EnumerateAttributes(F.getAttributes());
}
// Enumerate the aliases.
- for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I)
- EnumerateValue(I);
+ for (const GlobalAlias &GA : M.aliases())
+ EnumerateValue(&GA);
// Remember what is the cutoff between globalvalue's and other constants.
unsigned FirstConstant = Values.size();
// Enumerate the global variable initializers.
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- if (I->hasInitializer())
- EnumerateValue(I->getInitializer());
+ for (const GlobalVariable &GV : M.globals())
+ if (GV.hasInitializer())
+ EnumerateValue(GV.getInitializer());
// Enumerate the aliasees.
- for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I)
- EnumerateValue(I->getAliasee());
+ for (const GlobalAlias &GA : M.aliases())
+ EnumerateValue(GA.getAliasee());
// Enumerate the prefix data constants.
- for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasPrefixData())
- EnumerateValue(I->getPrefixData());
+ for (const Function &F : M)
+ if (F.hasPrefixData())
+ EnumerateValue(F.getPrefixData());
// Enumerate the prologue data constants.
+ for (const Function &F : M)
+ if (F.hasPrologueData())
+ EnumerateValue(F.getPrologueData());
+
+ // Enumerate the personality functions.
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasPrologueData())
- EnumerateValue(I->getPrologueData());
+ if (I->hasPersonalityFn())
+ EnumerateValue(I->getPersonalityFn());
// Enumerate the metadata type.
//
@@ -345,6 +354,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 +386,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 +422,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 +474,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 +554,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 +814,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/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h
index d363c1b..b2daa48 100644
--- a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/contrib/llvm/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);
@@ -190,6 +203,6 @@ private:
void EnumerateNamedMetadata(const Module &M);
};
-} // End llvm namespace
+} // namespace llvm
#endif
OpenPOWER on IntegriCloud