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.cpp88
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp3111
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h349
-rw-r--r--contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp371
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp39
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2020
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp41
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp540
-rw-r--r--contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h171
9 files changed, 6730 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp
new file mode 100644
index 0000000..5cd6c55
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp
@@ -0,0 +1,88 @@
+//===-- BitReader.cpp -----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/BitReader.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstring>
+#include <string>
+
+using namespace llvm;
+
+/* Builds a module from the bitcode in the specified memory buffer, returning a
+ reference to the module via the OutModule parameter. Returns 0 on success.
+ Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutModule, char **OutMessage) {
+ return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
+ OutMessage);
+}
+
+LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutModule,
+ char **OutMessage) {
+ std::string Message;
+
+ *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef),
+ &Message));
+ if (!*OutModule) {
+ if (OutMessage)
+ *OutMessage = strdup(Message.c_str());
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Reads a module from the specified path, returning via the OutModule parameter
+ a module provider which performs lazy deserialization. Returns 0 on success.
+ Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutM,
+ char **OutMessage) {
+ std::string Message;
+
+ *OutM = wrap(getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef),
+ &Message));
+ if (!*OutM) {
+ if (OutMessage)
+ *OutMessage = strdup(Message.c_str());
+ return 1;
+ }
+
+ return 0;
+
+}
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+ char **OutMessage) {
+ return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
+ OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
+LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage) {
+ return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
+ reinterpret_cast<LLVMModuleRef*>(OutMP),
+ OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage) {
+ return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
+ OutMP, OutMessage);
+}
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
new file mode 100644
index 0000000..f348843
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -0,0 +1,3111 @@
+//===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "BitcodeReader.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/AutoUpgrade.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/Support/DataStream.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+using namespace llvm;
+
+enum {
+ SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
+};
+
+void BitcodeReader::materializeForwardReferencedFunctions() {
+ while (!BlockAddrFwdRefs.empty()) {
+ Function *F = BlockAddrFwdRefs.begin()->first;
+ F->Materialize();
+ }
+}
+
+void BitcodeReader::FreeState() {
+ if (BufferOwned)
+ delete Buffer;
+ Buffer = 0;
+ std::vector<Type*>().swap(TypeList);
+ ValueList.clear();
+ MDValueList.clear();
+
+ std::vector<AttributeSet>().swap(MAttributes);
+ std::vector<BasicBlock*>().swap(FunctionBBs);
+ std::vector<Function*>().swap(FunctionsWithBodies);
+ DeferredFunctionInfo.clear();
+ MDKindMap.clear();
+
+ assert(BlockAddrFwdRefs.empty() && "Unresolved blockaddress fwd references");
+}
+
+//===----------------------------------------------------------------------===//
+// 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,
+ StrTy &Result) {
+ if (Idx > Record.size())
+ return true;
+
+ for (unsigned i = Idx, e = Record.size(); i != e; ++i)
+ Result += (char)Record[i];
+ return false;
+}
+
+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::DLLImportLinkage;
+ case 6: return GlobalValue::DLLExportLinkage;
+ case 7: return GlobalValue::ExternalWeakLinkage;
+ case 8: 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: return GlobalValue::LinkerPrivateLinkage;
+ case 14: return GlobalValue::LinkerPrivateWeakLinkage;
+ case 15: return GlobalValue::LinkOnceODRAutoHideLinkage;
+ }
+}
+
+static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
+ switch (Val) {
+ default: // Map unknown visibilities to default.
+ case 0: return GlobalValue::DefaultVisibility;
+ case 1: return GlobalValue::HiddenVisibility;
+ case 2: return GlobalValue::ProtectedVisibility;
+ }
+}
+
+static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
+ switch (Val) {
+ case 0: return GlobalVariable::NotThreadLocal;
+ default: // Map unknown non-zero value to general dynamic.
+ case 1: return GlobalVariable::GeneralDynamicTLSModel;
+ case 2: return GlobalVariable::LocalDynamicTLSModel;
+ case 3: return GlobalVariable::InitialExecTLSModel;
+ case 4: return GlobalVariable::LocalExecTLSModel;
+ }
+}
+
+static int GetDecodedCastOpcode(unsigned Val) {
+ switch (Val) {
+ default: return -1;
+ case bitc::CAST_TRUNC : return Instruction::Trunc;
+ case bitc::CAST_ZEXT : return Instruction::ZExt;
+ case bitc::CAST_SEXT : return Instruction::SExt;
+ case bitc::CAST_FPTOUI : return Instruction::FPToUI;
+ case bitc::CAST_FPTOSI : return Instruction::FPToSI;
+ case bitc::CAST_UITOFP : return Instruction::UIToFP;
+ case bitc::CAST_SITOFP : return Instruction::SIToFP;
+ case bitc::CAST_FPTRUNC : return Instruction::FPTrunc;
+ case bitc::CAST_FPEXT : return Instruction::FPExt;
+ case bitc::CAST_PTRTOINT: return Instruction::PtrToInt;
+ case bitc::CAST_INTTOPTR: return Instruction::IntToPtr;
+ case bitc::CAST_BITCAST : return Instruction::BitCast;
+ }
+}
+static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
+ switch (Val) {
+ default: return -1;
+ case bitc::BINOP_ADD:
+ return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
+ case bitc::BINOP_SUB:
+ return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
+ case bitc::BINOP_MUL:
+ return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
+ case bitc::BINOP_UDIV: return Instruction::UDiv;
+ case bitc::BINOP_SDIV:
+ return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
+ case bitc::BINOP_UREM: return 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;
+ }
+}
+
+static AtomicRMWInst::BinOp GetDecodedRMWOperation(unsigned Val) {
+ switch (Val) {
+ default: return AtomicRMWInst::BAD_BINOP;
+ case bitc::RMW_XCHG: return AtomicRMWInst::Xchg;
+ case bitc::RMW_ADD: return AtomicRMWInst::Add;
+ case bitc::RMW_SUB: return AtomicRMWInst::Sub;
+ case bitc::RMW_AND: return AtomicRMWInst::And;
+ case bitc::RMW_NAND: return AtomicRMWInst::Nand;
+ case bitc::RMW_OR: return AtomicRMWInst::Or;
+ case bitc::RMW_XOR: return AtomicRMWInst::Xor;
+ case bitc::RMW_MAX: return AtomicRMWInst::Max;
+ case bitc::RMW_MIN: return AtomicRMWInst::Min;
+ case bitc::RMW_UMAX: return AtomicRMWInst::UMax;
+ case bitc::RMW_UMIN: return AtomicRMWInst::UMin;
+ }
+}
+
+static AtomicOrdering GetDecodedOrdering(unsigned Val) {
+ switch (Val) {
+ case bitc::ORDERING_NOTATOMIC: return NotAtomic;
+ case bitc::ORDERING_UNORDERED: return Unordered;
+ case bitc::ORDERING_MONOTONIC: return Monotonic;
+ case bitc::ORDERING_ACQUIRE: return Acquire;
+ case bitc::ORDERING_RELEASE: return Release;
+ case bitc::ORDERING_ACQREL: return AcquireRelease;
+ default: // Map unknown orderings to sequentially-consistent.
+ case bitc::ORDERING_SEQCST: return SequentiallyConsistent;
+ }
+}
+
+static SynchronizationScope GetDecodedSynchScope(unsigned Val) {
+ switch (Val) {
+ case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread;
+ default: // Map unknown scopes to cross-thread.
+ case bitc::SYNCHSCOPE_CROSSTHREAD: return CrossThread;
+ }
+}
+
+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)
+ : 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;
+ }
+
+
+ /// Provide fast operand accessors
+ //DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+ };
+}
+
+// FIXME: can we inherit this from ConstantExpr?
+template <>
+struct OperandTraits<ConstantPlaceHolder> :
+ public FixedNumOperandTraits<ConstantPlaceHolder, 1> {
+};
+}
+
+
+void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) {
+ if (Idx == size()) {
+ push_back(V);
+ return;
+ }
+
+ if (Idx >= size())
+ resize(Idx+1);
+
+ WeakVH &OldV = ValuePtrs[Idx];
+ if (OldV == 0) {
+ OldV = V;
+ return;
+ }
+
+ // Handle constants and non-constants (e.g. instrs) differently for
+ // efficiency.
+ if (Constant *PHC = dyn_cast<Constant>(&*OldV)) {
+ ResolveConstants.push_back(std::make_pair(PHC, Idx));
+ OldV = V;
+ } else {
+ // If there was a forward reference to this value, replace it.
+ Value *PrevVal = OldV;
+ OldV->replaceAllUsesWith(V);
+ delete PrevVal;
+ }
+}
+
+
+Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
+ Type *Ty) {
+ if (Idx >= size())
+ resize(Idx + 1);
+
+ if (Value *V = ValuePtrs[Idx]) {
+ assert(Ty == V->getType() && "Type mismatch in constant table!");
+ return cast<Constant>(V);
+ }
+
+ // Create and return a placeholder, which will later be RAUW'd.
+ Constant *C = new ConstantPlaceHolder(Ty, Context);
+ ValuePtrs[Idx] = C;
+ return C;
+}
+
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
+ if (Idx >= size())
+ resize(Idx + 1);
+
+ if (Value *V = ValuePtrs[Idx]) {
+ assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");
+ return V;
+ }
+
+ // No type specified, must be invalid reference.
+ if (Ty == 0) return 0;
+
+ // Create and return a placeholder, which will later be RAUW'd.
+ Value *V = new Argument(Ty);
+ ValuePtrs[Idx] = V;
+ 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() {
+ // Sort the values by-pointer so that they are efficient to look up with a
+ // binary search.
+ std::sort(ResolveConstants.begin(), ResolveConstants.end());
+
+ SmallVector<Constant*, 64> NewOps;
+
+ while (!ResolveConstants.empty()) {
+ Value *RealVal = operator[](ResolveConstants.back().second);
+ Constant *Placeholder = ResolveConstants.back().first;
+ ResolveConstants.pop_back();
+
+ // Loop over all users of the placeholder, updating them to reference the
+ // new value. If they reference more than one placeholder, update them all
+ // at once.
+ while (!Placeholder->use_empty()) {
+ Value::use_iterator UI = Placeholder->use_begin();
+ User *U = *UI;
+
+ // If the using object isn't uniqued, just update the operands. This
+ // handles instructions and initializers for global variables.
+ if (!isa<Constant>(U) || isa<GlobalValue>(U)) {
+ UI.getUse().set(RealVal);
+ continue;
+ }
+
+ // Otherwise, we have a constant that uses the placeholder. Replace that
+ // constant with a new constant that has *all* placeholder uses updated.
+ Constant *UserC = cast<Constant>(U);
+ for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end();
+ I != E; ++I) {
+ Value *NewOp;
+ if (!isa<ConstantPlaceHolder>(*I)) {
+ // Not a placeholder reference.
+ NewOp = *I;
+ } else if (*I == Placeholder) {
+ // Common case is that it just references this one placeholder.
+ NewOp = RealVal;
+ } else {
+ // Otherwise, look up the placeholder in ResolveConstants.
+ ResolveConstantsTy::iterator It =
+ std::lower_bound(ResolveConstants.begin(), ResolveConstants.end(),
+ std::pair<Constant*, unsigned>(cast<Constant>(*I),
+ 0));
+ assert(It != ResolveConstants.end() && It->first == *I);
+ NewOp = operator[](It->second);
+ }
+
+ NewOps.push_back(cast<Constant>(NewOp));
+ }
+
+ // Make the new constant.
+ Constant *NewC;
+ if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) {
+ NewC = ConstantArray::get(UserCA->getType(), NewOps);
+ } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
+ NewC = ConstantStruct::get(UserCS->getType(), NewOps);
+ } else if (isa<ConstantVector>(UserC)) {
+ NewC = ConstantVector::get(NewOps);
+ } else {
+ assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr.");
+ NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps);
+ }
+
+ UserC->replaceAllUsesWith(NewC);
+ UserC->destroyConstant();
+ NewOps.clear();
+ }
+
+ // Update all ValueHandles, they should be the only users at this point.
+ Placeholder->replaceAllUsesWith(RealVal);
+ delete Placeholder;
+ }
+}
+
+void BitcodeReaderMDValueList::AssignValue(Value *V, unsigned Idx) {
+ if (Idx == size()) {
+ push_back(V);
+ return;
+ }
+
+ if (Idx >= size())
+ resize(Idx+1);
+
+ WeakVH &OldV = MDValuePtrs[Idx];
+ if (OldV == 0) {
+ OldV = V;
+ return;
+ }
+
+ // If there was a forward reference to this value, replace it.
+ MDNode *PrevVal = cast<MDNode>(OldV);
+ OldV->replaceAllUsesWith(V);
+ MDNode::deleteTemporary(PrevVal);
+ // Deleting PrevVal sets Idx value in MDValuePtrs to null. Set new
+ // value for Idx.
+ MDValuePtrs[Idx] = V;
+}
+
+Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
+ if (Idx >= size())
+ resize(Idx + 1);
+
+ if (Value *V = MDValuePtrs[Idx]) {
+ assert(V->getType()->isMetadataTy() && "Type mismatch in value table!");
+ return V;
+ }
+
+ // Create and return a placeholder, which will later be RAUW'd.
+ Value *V = MDNode::getTemporary(Context, ArrayRef<Value*>());
+ MDValuePtrs[Idx] = V;
+ return V;
+}
+
+Type *BitcodeReader::getTypeByID(unsigned ID) {
+ // The type table size is always specified correctly.
+ if (ID >= TypeList.size())
+ return 0;
+
+ if (Type *Ty = TypeList[ID])
+ return Ty;
+
+ // If we have a forward reference, the only possible case is when it is to a
+ // named struct. Just create a placeholder for now.
+ return TypeList[ID] = StructType::create(Context);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Functions for parsing blocks from the bitcode file
+//===----------------------------------------------------------------------===//
+
+
+/// \brief This fills an AttrBuilder object with the LLVM attributes that have
+/// been decoded from the given integer. This function must stay in sync with
+/// 'encodeLLVMAttributesForBitcode'.
+static void decodeLLVMAttributesForBitcode(AttrBuilder &B,
+ uint64_t EncodedAttrs) {
+ // FIXME: Remove in 4.0.
+
+ // The alignment is stored as a 16-bit raw value from bits 31--16. We shift
+ // the bits above 31 down by 11 bits.
+ unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
+ assert((!Alignment || isPowerOf2_32(Alignment)) &&
+ "Alignment must be a power of two.");
+
+ if (Alignment)
+ B.addAlignmentAttr(Alignment);
+ B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) |
+ (EncodedAttrs & 0xffff));
+}
+
+bool BitcodeReader::ParseAttributeBlock() {
+ if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID))
+ return Error("Malformed block record");
+
+ if (!MAttributes.empty())
+ return Error("Multiple PARAMATTR blocks found!");
+
+ SmallVector<uint64_t, 64> Record;
+
+ SmallVector<AttributeSet, 8> Attrs;
+
+ // Read all the records.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("Error at end of PARAMATTR block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: // Default behavior: ignore.
+ break;
+ case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...]
+ // FIXME: Remove in 4.0.
+ if (Record.size() & 1)
+ return Error("Invalid ENTRY record");
+
+ for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+ AttrBuilder B;
+ decodeLLVMAttributesForBitcode(B, Record[i+1]);
+ Attrs.push_back(AttributeSet::get(Context, Record[i], B));
+ }
+
+ MAttributes.push_back(AttributeSet::get(Context, Attrs));
+ Attrs.clear();
+ break;
+ }
+ case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...]
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ Attrs.push_back(MAttributeGroups[Record[i]]);
+
+ MAttributes.push_back(AttributeSet::get(Context, Attrs));
+ Attrs.clear();
+ break;
+ }
+ }
+ }
+}
+
+bool BitcodeReader::ParseAttributeGroupBlock() {
+ if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID))
+ return Error("Malformed block record");
+
+ if (!MAttributeGroups.empty())
+ return Error("Multiple PARAMATTR_GROUP blocks found!");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("Error at end of PARAMATTR_GROUP block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: // Default behavior: ignore.
+ break;
+ case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...]
+ if (Record.size() < 3)
+ return Error("Invalid ENTRY record");
+
+ uint64_t GrpID = Record[0];
+ uint64_t Idx = Record[1]; // Index of the object this attribute refers to.
+
+ AttrBuilder B;
+ for (unsigned i = 2, e = Record.size(); i != e; ++i) {
+ if (Record[i] == 0) { // Enum attribute
+ B.addAttribute(Attribute::AttrKind(Record[++i]));
+ } else if (Record[i] == 1) { // Align attribute
+ if (Attribute::AttrKind(Record[++i]) == Attribute::Alignment)
+ B.addAlignmentAttr(Record[++i]);
+ else
+ B.addStackAlignmentAttr(Record[++i]);
+ } else { // String attribute
+ assert((Record[i] == 3 || Record[i] == 4) &&
+ "Invalid attribute group entry");
+ bool HasValue = (Record[i++] == 4);
+ SmallString<64> KindStr;
+ SmallString<64> ValStr;
+
+ while (Record[i] != 0 && i != e)
+ KindStr += Record[i++];
+ assert(Record[i] == 0 && "Kind string not null terminated");
+
+ if (HasValue) {
+ // Has a value associated with it.
+ ++i; // Skip the '0' that terminates the "kind" string.
+ while (Record[i] != 0 && i != e)
+ ValStr += Record[i++];
+ assert(Record[i] == 0 && "Value string not null terminated");
+ }
+
+ B.addAttribute(KindStr.str(), ValStr.str());
+ }
+ }
+
+ MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B);
+ break;
+ }
+ }
+ }
+}
+
+bool BitcodeReader::ParseTypeTable() {
+ if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
+ return Error("Malformed block record");
+
+ return ParseTypeTableBody();
+}
+
+bool BitcodeReader::ParseTypeTableBody() {
+ if (!TypeList.empty())
+ return Error("Multiple TYPE_BLOCKs found!");
+
+ SmallVector<uint64_t, 64> Record;
+ unsigned NumRecords = 0;
+
+ SmallString<64> TypeName;
+
+ // Read all the records for this type table.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ Error("Error in the type table block");
+ return true;
+ case BitstreamEntry::EndBlock:
+ if (NumRecords != TypeList.size())
+ return Error("Invalid type forward reference in TYPE_BLOCK");
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ Type *ResultTy = 0;
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: return Error("unknown type in type table");
+ 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 TYPE_CODE_NUMENTRY record");
+ TypeList.resize(Record[0]);
+ continue;
+ case bitc::TYPE_CODE_VOID: // VOID
+ ResultTy = Type::getVoidTy(Context);
+ break;
+ case bitc::TYPE_CODE_HALF: // HALF
+ ResultTy = Type::getHalfTy(Context);
+ break;
+ case bitc::TYPE_CODE_FLOAT: // FLOAT
+ ResultTy = Type::getFloatTy(Context);
+ break;
+ case bitc::TYPE_CODE_DOUBLE: // DOUBLE
+ ResultTy = Type::getDoubleTy(Context);
+ break;
+ case bitc::TYPE_CODE_X86_FP80: // X86_FP80
+ ResultTy = Type::getX86_FP80Ty(Context);
+ break;
+ case bitc::TYPE_CODE_FP128: // FP128
+ ResultTy = Type::getFP128Ty(Context);
+ break;
+ case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+ ResultTy = Type::getPPC_FP128Ty(Context);
+ break;
+ case bitc::TYPE_CODE_LABEL: // LABEL
+ ResultTy = Type::getLabelTy(Context);
+ break;
+ case bitc::TYPE_CODE_METADATA: // METADATA
+ ResultTy = Type::getMetadataTy(Context);
+ break;
+ case bitc::TYPE_CODE_X86_MMX: // X86_MMX
+ ResultTy = Type::getX86_MMXTy(Context);
+ break;
+ case bitc::TYPE_CODE_INTEGER: // INTEGER: [width]
+ if (Record.size() < 1)
+ return Error("Invalid Integer type record");
+
+ ResultTy = IntegerType::get(Context, Record[0]);
+ break;
+ case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+ // [pointee type, address space]
+ if (Record.size() < 1)
+ return Error("Invalid POINTER type record");
+ unsigned AddressSpace = 0;
+ if (Record.size() == 2)
+ AddressSpace = Record[1];
+ ResultTy = getTypeByID(Record[0]);
+ if (ResultTy == 0) return Error("invalid element type in pointer type");
+ ResultTy = PointerType::get(ResultTy, AddressSpace);
+ break;
+ }
+ case bitc::TYPE_CODE_FUNCTION_OLD: {
+ // FIXME: attrid is dead, remove it in LLVM 4.0
+ // FUNCTION: [vararg, attrid, retty, paramty x N]
+ if (Record.size() < 3)
+ return Error("Invalid FUNCTION type record");
+ SmallVector<Type*, 8> ArgTys;
+ for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ ArgTys.push_back(T);
+ else
+ break;
+ }
+
+ ResultTy = getTypeByID(Record[2]);
+ if (ResultTy == 0 || ArgTys.size() < Record.size()-3)
+ return Error("invalid type in function type");
+
+ ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+ break;
+ }
+ case bitc::TYPE_CODE_FUNCTION: {
+ // FUNCTION: [vararg, retty, paramty x N]
+ if (Record.size() < 2)
+ return Error("Invalid FUNCTION type record");
+ SmallVector<Type*, 8> ArgTys;
+ for (unsigned i = 2, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ ArgTys.push_back(T);
+ else
+ break;
+ }
+
+ ResultTy = getTypeByID(Record[1]);
+ if (ResultTy == 0 || ArgTys.size() < Record.size()-2)
+ return Error("invalid type in function 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 STRUCT type record");
+ SmallVector<Type*, 8> EltTys;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ EltTys.push_back(T);
+ else
+ break;
+ }
+ if (EltTys.size() != Record.size()-1)
+ return Error("invalid type in struct 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 STRUCT_NAME record");
+ continue;
+
+ case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
+ if (Record.size() < 1)
+ return Error("Invalid STRUCT type record");
+
+ if (NumRecords >= TypeList.size())
+ 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]);
+ if (Res) {
+ Res->setName(TypeName);
+ TypeList[NumRecords] = 0;
+ } else // Otherwise, create a new struct.
+ Res = StructType::create(Context, TypeName);
+ TypeName.clear();
+
+ SmallVector<Type*, 8> EltTys;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ EltTys.push_back(T);
+ else
+ break;
+ }
+ if (EltTys.size() != Record.size()-1)
+ return Error("invalid STRUCT type record");
+ Res->setBody(EltTys, Record[0]);
+ ResultTy = Res;
+ break;
+ }
+ case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: []
+ if (Record.size() != 1)
+ return Error("Invalid OPAQUE type record");
+
+ if (NumRecords >= TypeList.size())
+ 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]);
+ if (Res) {
+ Res->setName(TypeName);
+ TypeList[NumRecords] = 0;
+ } else // Otherwise, create a new struct with no body.
+ Res = StructType::create(Context, TypeName);
+ TypeName.clear();
+ ResultTy = Res;
+ break;
+ }
+ case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
+ if (Record.size() < 2)
+ return Error("Invalid ARRAY type record");
+ if ((ResultTy = getTypeByID(Record[1])))
+ ResultTy = ArrayType::get(ResultTy, Record[0]);
+ else
+ return Error("Invalid ARRAY type element");
+ break;
+ case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
+ if (Record.size() < 2)
+ return Error("Invalid VECTOR type record");
+ if ((ResultTy = getTypeByID(Record[1])))
+ ResultTy = VectorType::get(ResultTy, Record[0]);
+ else
+ return Error("Invalid ARRAY type element");
+ break;
+ }
+
+ if (NumRecords >= TypeList.size())
+ return Error("invalid TYPE table");
+ assert(ResultTy && "Didn't read a type?");
+ assert(TypeList[NumRecords] == 0 && "Already read type?");
+ TypeList[NumRecords++] = ResultTy;
+ }
+}
+
+bool BitcodeReader::ParseValueSymbolTable() {
+ if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records for this value table.
+ SmallString<128> ValueName;
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed value symbol table block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ 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 VST_ENTRY record");
+ unsigned ValueID = Record[0];
+ if (ValueID >= ValueList.size())
+ return Error("Invalid Value ID in VST_ENTRY record");
+ Value *V = ValueList[ValueID];
+
+ V->setName(StringRef(ValueName.data(), ValueName.size()));
+ ValueName.clear();
+ break;
+ }
+ case bitc::VST_CODE_BBENTRY: {
+ if (ConvertToString(Record, 1, ValueName))
+ return Error("Invalid VST_BBENTRY record");
+ BasicBlock *BB = getBasicBlock(Record[0]);
+ if (BB == 0)
+ return Error("Invalid BB ID in VST_BBENTRY record");
+
+ BB->setName(StringRef(ValueName.data(), ValueName.size()));
+ ValueName.clear();
+ break;
+ }
+ }
+ }
+}
+
+bool BitcodeReader::ParseMetadata() {
+ unsigned NextMDValueNo = MDValueList.size();
+
+ if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ Error("malformed metadata block");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ bool IsFunctionLocal = false;
+ // Read a record.
+ Record.clear();
+ unsigned Code = Stream.readRecord(Entry.ID, Record);
+ switch (Code) {
+ default: // Default behavior: ignore.
+ break;
+ case bitc::METADATA_NAME: {
+ // Read name of the named metadata.
+ SmallString<8> Name(Record.begin(), Record.end());
+ 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;
+
+ // Read named metadata elements.
+ unsigned Size = Record.size();
+ NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata(Name);
+ for (unsigned i = 0; i != Size; ++i) {
+ MDNode *MD = dyn_cast<MDNode>(MDValueList.getValueFwdRef(Record[i]));
+ if (MD == 0)
+ return Error("Malformed metadata record");
+ NMD->addOperand(MD);
+ }
+ break;
+ }
+ case bitc::METADATA_FN_NODE:
+ IsFunctionLocal = true;
+ // fall-through
+ case bitc::METADATA_NODE: {
+ if (Record.size() % 2 == 1)
+ return Error("Invalid METADATA_NODE record");
+
+ unsigned Size = Record.size();
+ SmallVector<Value*, 8> Elts;
+ for (unsigned i = 0; i != Size; i += 2) {
+ Type *Ty = getTypeByID(Record[i]);
+ if (!Ty) return Error("Invalid METADATA_NODE record");
+ if (Ty->isMetadataTy())
+ Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
+ else if (!Ty->isVoidTy())
+ Elts.push_back(ValueList.getValueFwdRef(Record[i+1], Ty));
+ else
+ Elts.push_back(NULL);
+ }
+ Value *V = MDNode::getWhenValsUnresolved(Context, Elts, IsFunctionLocal);
+ IsFunctionLocal = false;
+ MDValueList.AssignValue(V, NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_STRING: {
+ SmallString<8> String(Record.begin(), Record.end());
+ Value *V = MDString::get(Context, String);
+ MDValueList.AssignValue(V, NextMDValueNo++);
+ break;
+ }
+ case bitc::METADATA_KIND: {
+ if (Record.size() < 2)
+ return Error("Invalid METADATA_KIND 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");
+ break;
+ }
+ }
+ }
+}
+
+/// decodeSignRotatedValue - 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;
+ if (V != 1)
+ return -(V >> 1);
+ // There is no such thing as -0 with integers. "-0" really means MININT.
+ return 1ULL << 63;
+}
+
+/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
+/// values and aliases that we can.
+bool BitcodeReader::ResolveGlobalAndAliasInits() {
+ std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
+ std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
+
+ GlobalInitWorklist.swap(GlobalInits);
+ AliasInitWorklist.swap(AliasInits);
+
+ while (!GlobalInitWorklist.empty()) {
+ unsigned ValID = GlobalInitWorklist.back().second;
+ if (ValID >= ValueList.size()) {
+ // Not ready to resolve this yet, it requires something later in the file.
+ GlobalInits.push_back(GlobalInitWorklist.back());
+ } else {
+ if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
+ GlobalInitWorklist.back().first->setInitializer(C);
+ else
+ return Error("Global variable initializer is not a constant!");
+ }
+ GlobalInitWorklist.pop_back();
+ }
+
+ while (!AliasInitWorklist.empty()) {
+ unsigned ValID = AliasInitWorklist.back().second;
+ if (ValID >= ValueList.size()) {
+ AliasInits.push_back(AliasInitWorklist.back());
+ } else {
+ if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
+ AliasInitWorklist.back().first->setAliasee(C);
+ else
+ return Error("Alias initializer is not a constant!");
+ }
+ AliasInitWorklist.pop_back();
+ }
+ return false;
+}
+
+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);
+
+ return APInt(TypeBits, Words);
+}
+
+bool BitcodeReader::ParseConstants() {
+ if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records for this value table.
+ Type *CurTy = Type::getInt32Ty(Context);
+ unsigned NextCstNo = ValueList.size();
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed block record in AST file");
+ case BitstreamEntry::EndBlock:
+ if (NextCstNo != ValueList.size())
+ return Error("Invalid constant reference!");
+
+ // Once all the constants have been read, go through and resolve forward
+ // references.
+ ValueList.ResolveConstantForwardRefs();
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ Value *V = 0;
+ unsigned BitCode = Stream.readRecord(Entry.ID, Record);
+ switch (BitCode) {
+ default: // Default behavior: unknown constant
+ case bitc::CST_CODE_UNDEF: // UNDEF
+ V = UndefValue::get(CurTy);
+ break;
+ case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid]
+ if (Record.empty())
+ return Error("Malformed CST_SETTYPE record");
+ if (Record[0] >= TypeList.size())
+ return Error("Invalid Type ID in CST_SETTYPE record");
+ CurTy = TypeList[Record[0]];
+ continue; // Skip the ValueList manipulation.
+ case bitc::CST_CODE_NULL: // NULL
+ V = Constant::getNullValue(CurTy);
+ break;
+ case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
+ if (!CurTy->isIntegerTy() || Record.empty())
+ return Error("Invalid CST_INTEGER 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 WIDE_INTEGER record");
+
+ 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 FLOAT record");
+ if (CurTy->isHalfTy())
+ V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf,
+ APInt(16, (uint16_t)Record[0])));
+ else if (CurTy->isFloatTy())
+ V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle,
+ APInt(32, (uint32_t)Record[0])));
+ else if (CurTy->isDoubleTy())
+ V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble,
+ APInt(64, Record[0])));
+ else if (CurTy->isX86_FP80Ty()) {
+ // Bits are not stored the same way as a normal i80 APInt, compensate.
+ uint64_t Rearrange[2];
+ Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
+ Rearrange[1] = Record[0] >> 48;
+ V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended,
+ APInt(80, Rearrange)));
+ } else if (CurTy->isFP128Ty())
+ V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad,
+ APInt(128, Record)));
+ else if (CurTy->isPPC_FP128Ty())
+ V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble,
+ APInt(128, Record)));
+ else
+ V = UndefValue::get(CurTy);
+ break;
+ }
+
+ case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
+ if (Record.empty())
+ return Error("Invalid CST_AGGREGATE record");
+
+ unsigned Size = Record.size();
+ SmallVector<Constant*, 16> Elts;
+
+ if (StructType *STy = dyn_cast<StructType>(CurTy)) {
+ for (unsigned i = 0; i != Size; ++i)
+ Elts.push_back(ValueList.getConstantFwdRef(Record[i],
+ STy->getElementType(i)));
+ V = ConstantStruct::get(STy, Elts);
+ } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
+ Type *EltTy = ATy->getElementType();
+ for (unsigned i = 0; i != Size; ++i)
+ Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+ V = ConstantArray::get(ATy, Elts);
+ } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
+ Type *EltTy = VTy->getElementType();
+ for (unsigned i = 0; i != Size; ++i)
+ Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+ V = ConstantVector::get(Elts);
+ } else {
+ V = UndefValue::get(CurTy);
+ }
+ break;
+ }
+ case bitc::CST_CODE_STRING: // STRING: [values]
+ case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
+ if (Record.empty())
+ return Error("Invalid CST_STRING record");
+
+ SmallString<16> Elts(Record.begin(), Record.end());
+ V = ConstantDataArray::getString(Context, Elts,
+ BitCode == bitc::CST_CODE_CSTRING);
+ break;
+ }
+ case bitc::CST_CODE_DATA: {// DATA: [n x value]
+ if (Record.empty())
+ return Error("Invalid CST_DATA record");
+
+ Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
+ unsigned Size = Record.size();
+
+ if (EltTy->isIntegerTy(8)) {
+ SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(16)) {
+ SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(32)) {
+ SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isIntegerTy(64)) {
+ SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end());
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isFloatTy()) {
+ SmallVector<float, 16> Elts(Size);
+ std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat);
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else if (EltTy->isDoubleTy()) {
+ SmallVector<double, 16> Elts(Size);
+ std::transform(Record.begin(), Record.end(), Elts.begin(),
+ BitsToDouble);
+ if (isa<VectorType>(CurTy))
+ V = ConstantDataVector::get(Context, Elts);
+ else
+ V = ConstantDataArray::get(Context, Elts);
+ } else {
+ return Error("Unknown element type in CE_DATA");
+ }
+ break;
+ }
+
+ case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval]
+ if (Record.size() < 3) return Error("Invalid CE_BINOP record");
+ int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
+ if (Opc < 0) {
+ V = UndefValue::get(CurTy); // Unknown binop.
+ } else {
+ Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
+ Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
+ unsigned Flags = 0;
+ if (Record.size() >= 4) {
+ if (Opc == Instruction::Add ||
+ Opc == Instruction::Sub ||
+ Opc == Instruction::Mul ||
+ Opc == Instruction::Shl) {
+ if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ Flags |= OverflowingBinaryOperator::NoSignedWrap;
+ if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+ } else if (Opc == Instruction::SDiv ||
+ Opc == Instruction::UDiv ||
+ Opc == Instruction::LShr ||
+ Opc == Instruction::AShr) {
+ if (Record[3] & (1 << bitc::PEO_EXACT))
+ Flags |= SDivOperator::IsExact;
+ }
+ }
+ V = ConstantExpr::get(Opc, LHS, RHS, Flags);
+ }
+ break;
+ }
+ case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
+ if (Record.size() < 3) return Error("Invalid CE_CAST 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 CE_CAST record");
+ Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
+ V = ConstantExpr::getCast(Opc, Op, CurTy);
+ }
+ break;
+ }
+ 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 CE_GEP record");
+ SmallVector<Constant*, 16> Elts;
+ for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+ Type *ElTy = getTypeByID(Record[i]);
+ if (!ElTy) return Error("Invalid CE_GEP record");
+ Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
+ }
+ ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
+ V = ConstantExpr::getGetElementPtr(Elts[0], Indices,
+ BitCode ==
+ 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 CE_SELECT record");
+ V = ConstantExpr::getSelect(
+ ValueList.getConstantFwdRef(Record[0],
+ Type::getInt1Ty(Context)),
+ ValueList.getConstantFwdRef(Record[1],CurTy),
+ ValueList.getConstantFwdRef(Record[2],CurTy));
+ break;
+ case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
+ if (Record.size() < 3) return Error("Invalid CE_EXTRACTELT record");
+ VectorType *OpTy =
+ dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+ if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record");
+ Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[2],
+ Type::getInt32Ty(Context));
+ V = ConstantExpr::getExtractElement(Op0, Op1);
+ break;
+ }
+ case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval]
+ VectorType *OpTy = dyn_cast<VectorType>(CurTy);
+ if (Record.size() < 3 || OpTy == 0)
+ return Error("Invalid CE_INSERTELT record");
+ Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
+ OpTy->getElementType());
+ Constant *Op2 = ValueList.getConstantFwdRef(Record[2],
+ Type::getInt32Ty(Context));
+ 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 == 0)
+ return Error("Invalid CE_SHUFFLEVEC record");
+ Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy);
+ Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+ OpTy->getNumElements());
+ Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy);
+ V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+ break;
+ }
+ case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval]
+ VectorType *RTy = dyn_cast<VectorType>(CurTy);
+ VectorType *OpTy =
+ dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+ if (Record.size() < 4 || RTy == 0 || OpTy == 0)
+ return Error("Invalid CE_SHUFVEC_EX record");
+ Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+ Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+ RTy->getNumElements());
+ Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy);
+ V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+ break;
+ }
+ case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred]
+ if (Record.size() < 4) return Error("Invalid CE_CMP record");
+ Type *OpTy = getTypeByID(Record[0]);
+ if (OpTy == 0) return Error("Invalid CE_CMP record");
+ Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+
+ if (OpTy->isFPOrFPVectorTy())
+ V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
+ else
+ V = ConstantExpr::getICmp(Record[3], Op0, Op1);
+ break;
+ }
+ // This maintains backward compatibility, pre-asm dialect keywords.
+ // FIXME: Remove with the 4.0 release.
+ case bitc::CST_CODE_INLINEASM_OLD: {
+ if (Record.size() < 2) return Error("Invalid INLINEASM 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 INLINEASM record");
+ unsigned ConstStrSize = Record[2+AsmStrSize];
+ if (3+AsmStrSize+ConstStrSize > Record.size())
+ return Error("Invalid INLINEASM record");
+
+ for (unsigned i = 0; i != AsmStrSize; ++i)
+ AsmStr += (char)Record[2+i];
+ for (unsigned i = 0; i != ConstStrSize; ++i)
+ ConstrStr += (char)Record[3+AsmStrSize+i];
+ PointerType *PTy = cast<PointerType>(CurTy);
+ V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+ break;
+ }
+ // This version adds support for the asm dialect keywords (e.g.,
+ // inteldialect).
+ case bitc::CST_CODE_INLINEASM: {
+ if (Record.size() < 2) return Error("Invalid INLINEASM 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 INLINEASM record");
+ unsigned ConstStrSize = Record[2+AsmStrSize];
+ if (3+AsmStrSize+ConstStrSize > Record.size())
+ return Error("Invalid INLINEASM record");
+
+ for (unsigned i = 0; i != AsmStrSize; ++i)
+ AsmStr += (char)Record[2+i];
+ for (unsigned i = 0; i != ConstStrSize; ++i)
+ ConstrStr += (char)Record[3+AsmStrSize+i];
+ PointerType *PTy = cast<PointerType>(CurTy);
+ V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect));
+ break;
+ }
+ case bitc::CST_CODE_BLOCKADDRESS:{
+ if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record");
+ Type *FnTy = getTypeByID(Record[0]);
+ if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record");
+ Function *Fn =
+ dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
+ if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
+
+ // If the function is already parsed we can insert the block address right
+ // away.
+ if (!Fn->empty()) {
+ Function::iterator BBI = Fn->begin(), BBE = Fn->end();
+ for (size_t I = 0, E = Record[2]; I != E; ++I) {
+ if (BBI == BBE)
+ return Error("Invalid blockaddress block #");
+ ++BBI;
+ }
+ V = BlockAddress::get(Fn, BBI);
+ } else {
+ // Otherwise insert a placeholder and remember it so it can be inserted
+ // when the function is parsed.
+ GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+ Type::getInt8Ty(Context),
+ false, GlobalValue::InternalLinkage,
+ 0, "");
+ BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+ V = FwdRef;
+ }
+ break;
+ }
+ }
+
+ ValueList.AssignValue(V, NextCstNo);
+ ++NextCstNo;
+ }
+}
+
+bool BitcodeReader::ParseUseLists() {
+ if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed use list block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a use list record.
+ Record.clear();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: // Default behavior: unknown type.
+ break;
+ case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD.
+ unsigned RecordLength = Record.size();
+ if (RecordLength < 1)
+ return Error ("Invalid UseList reader!");
+ UseListRecords.push_back(Record);
+ break;
+ }
+ }
+ }
+}
+
+/// 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.
+bool BitcodeReader::RememberAndSkipFunctionBody() {
+ // Get the function we are talking about.
+ if (FunctionsWithBodies.empty())
+ return Error("Insufficient function protos");
+
+ Function *Fn = FunctionsWithBodies.back();
+ FunctionsWithBodies.pop_back();
+
+ // Save the current stream state.
+ uint64_t CurBit = Stream.GetCurrentBitNo();
+ DeferredFunctionInfo[Fn] = CurBit;
+
+ // Skip over the function block for now.
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ return false;
+}
+
+bool BitcodeReader::GlobalCleanup() {
+ // Patch the initializers for globals and aliases up.
+ ResolveGlobalAndAliasInits();
+ if (!GlobalInits.empty() || !AliasInits.empty())
+ 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) {
+ Function *NewFn;
+ if (UpgradeIntrinsicFunction(FI, NewFn))
+ UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
+ }
+
+ // Look for global variables which need to be renamed.
+ for (Module::global_iterator
+ GI = TheModule->global_begin(), GE = TheModule->global_end();
+ GI != GE; ++GI)
+ UpgradeGlobalVariable(GI);
+ // Force deallocation of memory for these vectors to favor the client that
+ // want lazy deserialization.
+ std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+ std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+ return false;
+}
+
+bool BitcodeReader::ParseModule(bool Resume) {
+ if (Resume)
+ Stream.JumpToBit(NextUnreadBit);
+ else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+ std::vector<std::string> SectionTable;
+ std::vector<std::string> GCTable;
+
+ // Read all the records for this module.
+ while (1) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module block");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return GlobalCleanup();
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
+ default: // Skip unknown content.
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ case bitc::BLOCKINFO_BLOCK_ID:
+ if (Stream.ReadBlockInfoBlock())
+ return Error("Malformed BlockInfoBlock");
+ break;
+ case bitc::PARAMATTR_BLOCK_ID:
+ if (ParseAttributeBlock())
+ return true;
+ break;
+ case bitc::PARAMATTR_GROUP_BLOCK_ID:
+ if (ParseAttributeGroupBlock())
+ return true;
+ break;
+ case bitc::TYPE_BLOCK_ID_NEW:
+ if (ParseTypeTable())
+ return true;
+ break;
+ case bitc::VALUE_SYMTAB_BLOCK_ID:
+ if (ParseValueSymbolTable())
+ return true;
+ SeenValueSymbolTable = true;
+ break;
+ case bitc::CONSTANTS_BLOCK_ID:
+ if (ParseConstants() || ResolveGlobalAndAliasInits())
+ return true;
+ break;
+ case bitc::METADATA_BLOCK_ID:
+ if (ParseMetadata())
+ return true;
+ break;
+ case bitc::FUNCTION_BLOCK_ID:
+ // If this is the first function body we've seen, reverse the
+ // FunctionsWithBodies list.
+ if (!SeenFirstFunctionBody) {
+ std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
+ if (GlobalCleanup())
+ return true;
+ SeenFirstFunctionBody = true;
+ }
+
+ if (RememberAndSkipFunctionBody())
+ return true;
+ // For streaming bitcode, suspend parsing when we reach the function
+ // bodies. Subsequent materialization calls will resume it when
+ // necessary. For streaming, the function bodies must be at the end of
+ // 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) {
+ NextUnreadBit = Stream.GetCurrentBitNo();
+ return false;
+ }
+ break;
+ case bitc::USELIST_BLOCK_ID:
+ if (ParseUseLists())
+ return true;
+ break;
+ }
+ continue;
+
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+
+ // Read a record.
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: break; // Default behavior, ignore unknown content.
+ case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
+ if (Record.size() < 1)
+ return Error("Malformed MODULE_CODE_VERSION");
+ // Only version #0 and #1 are supported so far.
+ unsigned module_version = Record[0];
+ switch (module_version) {
+ default: return Error("Unknown bitstream version!");
+ case 0:
+ UseRelativeIDs = false;
+ break;
+ case 1:
+ UseRelativeIDs = true;
+ break;
+ }
+ break;
+ }
+ case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
+ std::string S;
+ if (ConvertToString(Record, 0, S))
+ return Error("Invalid MODULE_CODE_TRIPLE 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 MODULE_CODE_DATALAYOUT 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 MODULE_CODE_ASM 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 MODULE_CODE_DEPLIB record");
+ // Ignore value.
+ break;
+ }
+ case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N]
+ std::string S;
+ if (ConvertToString(Record, 0, S))
+ return Error("Invalid MODULE_CODE_SECTIONNAME 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 MODULE_CODE_GCNAME record");
+ GCTable.push_back(S);
+ break;
+ }
+ // GLOBALVAR: [pointer type, isconst, initid,
+ // linkage, alignment, section, visibility, threadlocal,
+ // unnamed_addr]
+ case bitc::MODULE_CODE_GLOBALVAR: {
+ if (Record.size() < 6)
+ return Error("Invalid MODULE_CODE_GLOBALVAR record");
+ Type *Ty = getTypeByID(Record[0]);
+ if (!Ty) return Error("Invalid MODULE_CODE_GLOBALVAR record");
+ if (!Ty->isPointerTy())
+ return Error("Global not a pointer type!");
+ 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;
+ std::string Section;
+ if (Record[5]) {
+ if (Record[5]-1 >= SectionTable.size())
+ return Error("Invalid section ID");
+ Section = SectionTable[Record[5]-1];
+ }
+ GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
+ if (Record.size() > 6)
+ Visibility = GetDecodedVisibility(Record[6]);
+
+ GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
+ if (Record.size() > 7)
+ TLM = GetDecodedThreadLocalMode(Record[7]);
+
+ bool UnnamedAddr = false;
+ if (Record.size() > 8)
+ UnnamedAddr = Record[8];
+
+ bool ExternallyInitialized = false;
+ if (Record.size() > 9)
+ ExternallyInitialized = Record[9];
+
+ GlobalVariable *NewGV =
+ new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0,
+ TLM, AddressSpace, ExternallyInitialized);
+ NewGV->setAlignment(Alignment);
+ if (!Section.empty())
+ NewGV->setSection(Section);
+ NewGV->setVisibility(Visibility);
+ NewGV->setUnnamedAddr(UnnamedAddr);
+
+ ValueList.push_back(NewGV);
+
+ // Remember which value to use for the global initializer.
+ if (unsigned InitID = Record[2])
+ GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
+ break;
+ }
+ // FUNCTION: [type, callingconv, isproto, linkage, paramattr,
+ // alignment, section, visibility, gc, unnamed_addr]
+ case bitc::MODULE_CODE_FUNCTION: {
+ if (Record.size() < 8)
+ return Error("Invalid MODULE_CODE_FUNCTION record");
+ Type *Ty = getTypeByID(Record[0]);
+ if (!Ty) return Error("Invalid MODULE_CODE_FUNCTION record");
+ if (!Ty->isPointerTy())
+ return Error("Function not a pointer type!");
+ FunctionType *FTy =
+ dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
+ if (!FTy)
+ return Error("Function not a pointer to function type!");
+
+ 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]));
+ Func->setAttributes(getAttributes(Record[4]));
+
+ Func->setAlignment((1 << Record[5]) >> 1);
+ if (Record[6]) {
+ if (Record[6]-1 >= SectionTable.size())
+ return Error("Invalid section ID");
+ Func->setSection(SectionTable[Record[6]-1]);
+ }
+ Func->setVisibility(GetDecodedVisibility(Record[7]));
+ if (Record.size() > 8 && Record[8]) {
+ if (Record[8]-1 > GCTable.size())
+ return Error("Invalid GC ID");
+ Func->setGC(GCTable[Record[8]-1].c_str());
+ }
+ bool UnnamedAddr = false;
+ if (Record.size() > 9)
+ UnnamedAddr = Record[9];
+ Func->setUnnamedAddr(UnnamedAddr);
+ ValueList.push_back(Func);
+
+ // If this is a function with a body, remember the prototype we are
+ // creating now, so that we can match up the body with them later.
+ if (!isProto) {
+ FunctionsWithBodies.push_back(Func);
+ if (LazyStreamer) DeferredFunctionInfo[Func] = 0;
+ }
+ break;
+ }
+ // ALIAS: [alias type, aliasee val#, linkage]
+ // ALIAS: [alias type, aliasee val#, linkage, visibility]
+ case bitc::MODULE_CODE_ALIAS: {
+ if (Record.size() < 3)
+ return Error("Invalid MODULE_ALIAS record");
+ Type *Ty = getTypeByID(Record[0]);
+ if (!Ty) return Error("Invalid MODULE_ALIAS record");
+ if (!Ty->isPointerTy())
+ return Error("Function not a pointer type!");
+
+ GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
+ "", 0, TheModule);
+ // Old bitcode files didn't have visibility field.
+ if (Record.size() > 3)
+ NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+ ValueList.push_back(NewGA);
+ AliasInits.push_back(std::make_pair(NewGA, Record[1]));
+ break;
+ }
+ /// MODULE_CODE_PURGEVALS: [numvals]
+ 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 MODULE_PURGEVALS record");
+ ValueList.shrinkTo(Record[0]);
+ break;
+ }
+ Record.clear();
+ }
+}
+
+bool BitcodeReader::ParseBitcodeInto(Module *M) {
+ TheModule = 0;
+
+ if (InitStream()) return true;
+
+ // Sniff for the signature.
+ if (Stream.Read(8) != 'B' ||
+ Stream.Read(8) != 'C' ||
+ Stream.Read(4) != 0x0 ||
+ Stream.Read(4) != 0xC ||
+ Stream.Read(4) != 0xE ||
+ Stream.Read(4) != 0xD)
+ 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 false;
+
+ BitstreamEntry Entry =
+ Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module file");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return false;
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
+ case bitc::BLOCKINFO_BLOCK_ID:
+ if (Stream.ReadBlockInfoBlock())
+ return Error("Malformed BlockInfoBlock");
+ break;
+ case bitc::MODULE_BLOCK_ID:
+ // Reject multiple MODULE_BLOCK's in a single bitstream.
+ if (TheModule)
+ return Error("Multiple MODULE_BLOCKs in same stream");
+ TheModule = M;
+ if (ParseModule(false))
+ return true;
+ if (LazyStreamer) return false;
+ break;
+ default:
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ }
+ continue;
+ case BitstreamEntry::Record:
+ // There should be no records in the top-level of blocks.
+
+ // 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 false;
+
+ return Error("Invalid record at top-level");
+ }
+ }
+}
+
+bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
+ if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records for this module.
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed module block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ 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 MODULE_CODE_TRIPLE record");
+ Triple = S;
+ break;
+ }
+ }
+ Record.clear();
+ }
+}
+
+bool BitcodeReader::ParseTriple(std::string &Triple) {
+ if (InitStream()) return true;
+
+ // Sniff for the signature.
+ if (Stream.Read(8) != 'B' ||
+ Stream.Read(8) != 'C' ||
+ Stream.Read(4) != 0x0 ||
+ Stream.Read(4) != 0xC ||
+ Stream.Read(4) != 0xE ||
+ Stream.Read(4) != 0xD)
+ 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) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ Error("malformed module file");
+ return true;
+ case BitstreamEntry::EndBlock:
+ return false;
+
+ case BitstreamEntry::SubBlock:
+ if (Entry.ID == bitc::MODULE_BLOCK_ID)
+ return ParseModuleTriple(Triple);
+
+ // Ignore other sub-blocks.
+ if (Stream.SkipBlock()) {
+ Error("malformed block record in AST file");
+ return true;
+ }
+ continue;
+
+ case BitstreamEntry::Record:
+ Stream.skipRecord(Entry.ID);
+ continue;
+ }
+ }
+}
+
+/// ParseMetadataAttachment - Parse metadata attachments.
+bool BitcodeReader::ParseMetadataAttachment() {
+ if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+ while (1) {
+ BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::SubBlock: // Handled for us already.
+ case BitstreamEntry::Error:
+ return Error("malformed metadata block");
+ case BitstreamEntry::EndBlock:
+ return false;
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a metadata attachment record.
+ Record.clear();
+ switch (Stream.readRecord(Entry.ID, Record)) {
+ default: // Default behavior: ignore.
+ break;
+ case bitc::METADATA_ATTACHMENT: {
+ unsigned RecordLength = Record.size();
+ if (Record.empty() || (RecordLength - 1) % 2 == 1)
+ return Error ("Invalid METADATA_ATTACHMENT reader!");
+ 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 metadata kind ID");
+ Value *Node = MDValueList.getValueFwdRef(Record[i+1]);
+ Inst->setMetadata(I->second, cast<MDNode>(Node));
+ }
+ break;
+ }
+ }
+ }
+}
+
+/// ParseFunctionBody - Lazily parse the specified function body block.
+bool BitcodeReader::ParseFunctionBody(Function *F) {
+ if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
+ return Error("Malformed block record");
+
+ InstructionList.clear();
+ unsigned ModuleValueListSize = ValueList.size();
+ unsigned ModuleMDValueListSize = MDValueList.size();
+
+ // Add all the function arguments to the value table.
+ for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ ValueList.push_back(I);
+
+ unsigned NextValueNo = ValueList.size();
+ BasicBlock *CurBB = 0;
+ unsigned CurBBNo = 0;
+
+ DebugLoc LastLoc;
+
+ // Read all the records.
+ SmallVector<uint64_t, 64> Record;
+ while (1) {
+ BitstreamEntry Entry = Stream.advance();
+
+ switch (Entry.Kind) {
+ case BitstreamEntry::Error:
+ return Error("Bitcode error in function block");
+ case BitstreamEntry::EndBlock:
+ goto OutOfRecordLoop;
+
+ case BitstreamEntry::SubBlock:
+ switch (Entry.ID) {
+ default: // Skip unknown content.
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ case bitc::CONSTANTS_BLOCK_ID:
+ if (ParseConstants()) return true;
+ NextValueNo = ValueList.size();
+ break;
+ case bitc::VALUE_SYMTAB_BLOCK_ID:
+ if (ParseValueSymbolTable()) return true;
+ break;
+ case bitc::METADATA_ATTACHMENT_ID:
+ if (ParseMetadataAttachment()) return true;
+ break;
+ case bitc::METADATA_BLOCK_ID:
+ if (ParseMetadata()) return true;
+ break;
+ }
+ continue;
+
+ case BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read a record.
+ Record.clear();
+ Instruction *I = 0;
+ unsigned BitCode = Stream.readRecord(Entry.ID, Record);
+ switch (BitCode) {
+ default: // Default behavior: reject
+ return Error("Unknown instruction");
+ case bitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks]
+ if (Record.size() < 1 || Record[0] == 0)
+ return Error("Invalid DECLAREBLOCKS record");
+ // Create all the basic blocks for the function.
+ FunctionBBs.resize(Record[0]);
+ for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i)
+ FunctionBBs[i] = BasicBlock::Create(Context, "", F);
+ CurBB = FunctionBBs[0];
+ continue;
+
+ case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
+ // This record indicates that the last instruction is at the same
+ // location as the previous instruction with a location.
+ I = 0;
+
+ // Get the last instruction emitted.
+ if (CurBB && !CurBB->empty())
+ I = &CurBB->back();
+ else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+ !FunctionBBs[CurBBNo-1]->empty())
+ I = &FunctionBBs[CurBBNo-1]->back();
+
+ if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
+ I->setDebugLoc(LastLoc);
+ I = 0;
+ continue;
+
+ case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
+ I = 0; // Get the last instruction emitted.
+ if (CurBB && !CurBB->empty())
+ I = &CurBB->back();
+ else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+ !FunctionBBs[CurBBNo-1]->empty())
+ I = &FunctionBBs[CurBBNo-1]->back();
+ if (I == 0 || Record.size() < 4)
+ return Error("Invalid FUNC_CODE_DEBUG_LOC record");
+
+ unsigned Line = Record[0], Col = Record[1];
+ unsigned ScopeID = Record[2], IAID = Record[3];
+
+ MDNode *Scope = 0, *IA = 0;
+ if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
+ if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
+ LastLoc = DebugLoc::get(Line, Col, Scope, IA);
+ I->setDebugLoc(LastLoc);
+ I = 0;
+ continue;
+ }
+
+ case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
+ unsigned OpNum = 0;
+ Value *LHS, *RHS;
+ if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
+ OpNum+1 > Record.size())
+ return Error("Invalid BINOP record");
+
+ int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
+ if (Opc == -1) return Error("Invalid BINOP record");
+ I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
+ InstructionList.push_back(I);
+ if (OpNum < Record.size()) {
+ if (Opc == Instruction::Add ||
+ Opc == Instruction::Sub ||
+ Opc == Instruction::Mul ||
+ Opc == Instruction::Shl) {
+ if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
+ if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
+ } else if (Opc == Instruction::SDiv ||
+ Opc == Instruction::UDiv ||
+ Opc == Instruction::LShr ||
+ Opc == Instruction::AShr) {
+ if (Record[OpNum] & (1 << bitc::PEO_EXACT))
+ cast<BinaryOperator>(I)->setIsExact(true);
+ } else if (isa<FPMathOperator>(I)) {
+ FastMathFlags FMF;
+ if (0 != (Record[OpNum] & FastMathFlags::UnsafeAlgebra))
+ FMF.setUnsafeAlgebra();
+ if (0 != (Record[OpNum] & FastMathFlags::NoNaNs))
+ FMF.setNoNaNs();
+ if (0 != (Record[OpNum] & FastMathFlags::NoInfs))
+ FMF.setNoInfs();
+ if (0 != (Record[OpNum] & FastMathFlags::NoSignedZeros))
+ FMF.setNoSignedZeros();
+ if (0 != (Record[OpNum] & FastMathFlags::AllowReciprocal))
+ FMF.setAllowReciprocal();
+ if (FMF.any())
+ I->setFastMathFlags(FMF);
+ }
+
+ }
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
+ unsigned OpNum = 0;
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+ OpNum+2 != Record.size())
+ return Error("Invalid CAST record");
+
+ Type *ResTy = getTypeByID(Record[OpNum]);
+ int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
+ if (Opc == -1 || ResTy == 0)
+ return Error("Invalid CAST record");
+ I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_INBOUNDS_GEP:
+ case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
+ unsigned OpNum = 0;
+ Value *BasePtr;
+ if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
+ return Error("Invalid GEP record");
+
+ SmallVector<Value*, 16> GEPIdx;
+ while (OpNum != Record.size()) {
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+ return Error("Invalid GEP record");
+ GEPIdx.push_back(Op);
+ }
+
+ I = GetElementPtrInst::Create(BasePtr, GEPIdx);
+ InstructionList.push_back(I);
+ if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
+ cast<GetElementPtrInst>(I)->setIsInBounds(true);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_EXTRACTVAL: {
+ // EXTRACTVAL: [opty, opval, n x indices]
+ unsigned OpNum = 0;
+ Value *Agg;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+ return Error("Invalid EXTRACTVAL record");
+
+ SmallVector<unsigned, 4> EXTRACTVALIdx;
+ for (unsigned RecSize = Record.size();
+ OpNum != RecSize; ++OpNum) {
+ uint64_t Index = Record[OpNum];
+ if ((unsigned)Index != Index)
+ return Error("Invalid EXTRACTVAL index");
+ EXTRACTVALIdx.push_back((unsigned)Index);
+ }
+
+ I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_INSERTVAL: {
+ // INSERTVAL: [opty, opval, opty, opval, n x indices]
+ unsigned OpNum = 0;
+ Value *Agg;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+ return Error("Invalid INSERTVAL record");
+ Value *Val;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val))
+ return Error("Invalid INSERTVAL record");
+
+ SmallVector<unsigned, 4> INSERTVALIdx;
+ for (unsigned RecSize = Record.size();
+ OpNum != RecSize; ++OpNum) {
+ uint64_t Index = Record[OpNum];
+ if ((unsigned)Index != Index)
+ return Error("Invalid INSERTVAL index");
+ INSERTVALIdx.push_back((unsigned)Index);
+ }
+
+ I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
+ // obsolete form of select
+ // handles select i1 ... in old bitcode
+ unsigned OpNum = 0;
+ Value *TrueVal, *FalseVal, *Cond;
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+ popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
+ popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond))
+ return Error("Invalid SELECT record");
+
+ I = SelectInst::Create(Cond, TrueVal, FalseVal);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_VSELECT: {// VSELECT: [ty,opval,opval,predty,pred]
+ // new form of select
+ // handles select i1 or select [N x i1]
+ unsigned OpNum = 0;
+ Value *TrueVal, *FalseVal, *Cond;
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+ popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
+ getValueTypePair(Record, OpNum, NextValueNo, Cond))
+ return Error("Invalid SELECT 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 SELECT condition type");
+ } else {
+ // expect i1
+ if (Cond->getType() != Type::getInt1Ty(Context))
+ return Error("Invalid SELECT condition type");
+ }
+
+ I = SelectInst::Create(Cond, TrueVal, FalseVal);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval]
+ unsigned OpNum = 0;
+ Value *Vec, *Idx;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
+ popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
+ return Error("Invalid EXTRACTELT record");
+ I = ExtractElementInst::Create(Vec, Idx);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ 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,
+ cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
+ popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
+ return Error("Invalid INSERTELT record");
+ I = InsertElementInst::Create(Vec, Elt, Idx);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
+ unsigned OpNum = 0;
+ Value *Vec1, *Vec2, *Mask;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
+ popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2))
+ return Error("Invalid SHUFFLEVEC record");
+
+ if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
+ return Error("Invalid SHUFFLEVEC record");
+ I = new ShuffleVectorInst(Vec1, Vec2, Mask);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_CMP: // CMP: [opty, opval, opval, pred]
+ // Old form of ICmp/FCmp returning bool
+ // Existed to differentiate between icmp/fcmp and vicmp/vfcmp which were
+ // both legal on vectors but had different behaviour.
+ case bitc::FUNC_CODE_INST_CMP2: { // CMP2: [opty, opval, opval, pred]
+ // FCmp/ICmp returning bool or vector of bool
+
+ unsigned OpNum = 0;
+ Value *LHS, *RHS;
+ if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
+ OpNum+1 != Record.size())
+ return Error("Invalid CMP record");
+
+ if (LHS->getType()->isFPOrFPVectorTy())
+ I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
+ else
+ I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_RET: // RET: [opty,opval<optional>]
+ {
+ unsigned Size = Record.size();
+ if (Size == 0) {
+ I = ReturnInst::Create(Context);
+ InstructionList.push_back(I);
+ break;
+ }
+
+ unsigned OpNum = 0;
+ Value *Op = NULL;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+ return Error("Invalid RET record");
+ if (OpNum != Record.size())
+ return Error("Invalid RET record");
+
+ I = ReturnInst::Create(Context, Op);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
+ if (Record.size() != 1 && Record.size() != 3)
+ return Error("Invalid BR record");
+ BasicBlock *TrueDest = getBasicBlock(Record[0]);
+ if (TrueDest == 0)
+ return Error("Invalid BR record");
+
+ if (Record.size() == 1) {
+ I = BranchInst::Create(TrueDest);
+ InstructionList.push_back(I);
+ }
+ else {
+ BasicBlock *FalseDest = getBasicBlock(Record[1]);
+ Value *Cond = getValue(Record, 2, NextValueNo,
+ Type::getInt1Ty(Context));
+ if (FalseDest == 0 || Cond == 0)
+ return Error("Invalid BR record");
+ I = BranchInst::Create(TrueDest, FalseDest, Cond);
+ InstructionList.push_back(I);
+ }
+ break;
+ }
+ case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
+ // Check magic
+ if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
+ // New SwitchInst format with case ranges.
+
+ Type *OpTy = getTypeByID(Record[1]);
+ unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
+
+ Value *Cond = getValue(Record, 2, NextValueNo, OpTy);
+ BasicBlock *Default = getBasicBlock(Record[3]);
+ if (OpTy == 0 || Cond == 0 || Default == 0)
+ return Error("Invalid SWITCH record");
+
+ unsigned NumCases = Record[4];
+
+ SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+ InstructionList.push_back(SI);
+
+ unsigned CurIdx = 5;
+ for (unsigned i = 0; i != NumCases; ++i) {
+ IntegersSubsetToBB CaseBuilder;
+ unsigned NumItems = Record[CurIdx++];
+ for (unsigned ci = 0; ci != NumItems; ++ci) {
+ bool isSingleNumber = Record[CurIdx++];
+
+ APInt Low;
+ unsigned ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ Low = ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
+ ValueBitWidth);
+ CurIdx += ActiveWords;
+
+ if (!isSingleNumber) {
+ ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ APInt High =
+ ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
+ ValueBitWidth);
+
+ CaseBuilder.add(IntItem::fromType(OpTy, Low),
+ IntItem::fromType(OpTy, High));
+ CurIdx += ActiveWords;
+ } else
+ CaseBuilder.add(IntItem::fromType(OpTy, Low));
+ }
+ BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
+ IntegersSubset Case = CaseBuilder.getCase();
+ SI->addCase(Case, DestBB);
+ }
+ uint16_t Hash = SI->hash();
+ if (Hash != (Record[0] & 0xFFFF))
+ return Error("Invalid SWITCH record");
+ I = SI;
+ break;
+ }
+
+ // Old SwitchInst format without case ranges.
+
+ if (Record.size() < 3 || (Record.size() & 1) == 0)
+ return Error("Invalid SWITCH record");
+ Type *OpTy = getTypeByID(Record[0]);
+ Value *Cond = getValue(Record, 1, NextValueNo, OpTy);
+ BasicBlock *Default = getBasicBlock(Record[2]);
+ if (OpTy == 0 || Cond == 0 || Default == 0)
+ return Error("Invalid SWITCH record");
+ unsigned NumCases = (Record.size()-3)/2;
+ SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+ InstructionList.push_back(SI);
+ for (unsigned i = 0, e = NumCases; i != e; ++i) {
+ ConstantInt *CaseVal =
+ dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
+ BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
+ if (CaseVal == 0 || DestBB == 0) {
+ delete SI;
+ return Error("Invalid SWITCH record!");
+ }
+ SI->addCase(CaseVal, DestBB);
+ }
+ I = SI;
+ break;
+ }
+ case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...]
+ if (Record.size() < 2)
+ return Error("Invalid INDIRECTBR record");
+ Type *OpTy = getTypeByID(Record[0]);
+ Value *Address = getValue(Record, 1, NextValueNo, OpTy);
+ if (OpTy == 0 || Address == 0)
+ return Error("Invalid INDIRECTBR record");
+ unsigned NumDests = Record.size()-2;
+ IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests);
+ InstructionList.push_back(IBI);
+ for (unsigned i = 0, e = NumDests; i != e; ++i) {
+ if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) {
+ IBI->addDestination(DestBB);
+ } else {
+ delete IBI;
+ return Error("Invalid INDIRECTBR record!");
+ }
+ }
+ I = IBI;
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_INVOKE: {
+ // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
+ if (Record.size() < 4) return Error("Invalid INVOKE record");
+ AttributeSet PAL = getAttributes(Record[0]);
+ unsigned CCInfo = Record[1];
+ BasicBlock *NormalBB = getBasicBlock(Record[2]);
+ BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+
+ unsigned OpNum = 4;
+ Value *Callee;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+ return Error("Invalid INVOKE record");
+
+ PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
+ FunctionType *FTy = !CalleeTy ? 0 :
+ dyn_cast<FunctionType>(CalleeTy->getElementType());
+
+ // Check that the right number of fixed parameters are here.
+ if (FTy == 0 || NormalBB == 0 || UnwindBB == 0 ||
+ Record.size() < OpNum+FTy->getNumParams())
+ return Error("Invalid INVOKE record");
+
+ 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() == 0) return Error("Invalid INVOKE record");
+ }
+
+ if (!FTy->isVarArg()) {
+ if (Record.size() != OpNum)
+ return Error("Invalid INVOKE record");
+ } else {
+ // Read type/value pairs for varargs params.
+ while (OpNum != Record.size()) {
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+ return Error("Invalid INVOKE 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)->setAttributes(PAL);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval]
+ unsigned Idx = 0;
+ Value *Val = 0;
+ if (getValueTypePair(Record, Idx, NextValueNo, Val))
+ return Error("Invalid RESUME record");
+ I = ResumeInst::Create(Val);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
+ I = new UnreachableInst(Context);
+ InstructionList.push_back(I);
+ break;
+ case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
+ if (Record.size() < 1 || ((Record.size()-1)&1))
+ return Error("Invalid PHI record");
+ Type *Ty = getTypeByID(Record[0]);
+ if (!Ty) return Error("Invalid PHI record");
+
+ PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
+ InstructionList.push_back(PN);
+
+ for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
+ Value *V;
+ // With the new function encoding, it is possible that operands have
+ // negative IDs (for forward references). Use a signed VBR
+ // representation to keep the encoding small.
+ if (UseRelativeIDs)
+ V = getValueSigned(Record, 1+i, NextValueNo, Ty);
+ else
+ V = getValue(Record, 1+i, NextValueNo, Ty);
+ BasicBlock *BB = getBasicBlock(Record[2+i]);
+ if (!V || !BB) return Error("Invalid PHI record");
+ PN->addIncoming(V, BB);
+ }
+ I = PN;
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_LANDINGPAD: {
+ // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?]
+ unsigned Idx = 0;
+ if (Record.size() < 4)
+ return Error("Invalid LANDINGPAD record");
+ Type *Ty = getTypeByID(Record[Idx++]);
+ if (!Ty) return Error("Invalid LANDINGPAD record");
+ Value *PersFn = 0;
+ if (getValueTypePair(Record, Idx, NextValueNo, PersFn))
+ return Error("Invalid LANDINGPAD record");
+
+ bool IsCleanup = !!Record[Idx++];
+ unsigned NumClauses = Record[Idx++];
+ LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses);
+ LP->setCleanup(IsCleanup);
+ for (unsigned J = 0; J != NumClauses; ++J) {
+ LandingPadInst::ClauseType CT =
+ LandingPadInst::ClauseType(Record[Idx++]); (void)CT;
+ Value *Val;
+
+ if (getValueTypePair(Record, Idx, NextValueNo, Val)) {
+ delete LP;
+ return Error("Invalid LANDINGPAD record");
+ }
+
+ assert((CT != LandingPadInst::Catch ||
+ !isa<ArrayType>(Val->getType())) &&
+ "Catch clause has a invalid type!");
+ assert((CT != LandingPadInst::Filter ||
+ isa<ArrayType>(Val->getType())) &&
+ "Filter clause has invalid type!");
+ LP->addClause(Val);
+ }
+
+ I = LP;
+ InstructionList.push_back(I);
+ break;
+ }
+
+ case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
+ if (Record.size() != 4)
+ return Error("Invalid ALLOCA record");
+ PointerType *Ty =
+ dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+ Type *OpTy = getTypeByID(Record[1]);
+ Value *Size = getFnValueByID(Record[2], OpTy);
+ unsigned Align = Record[3];
+ if (!Ty || !Size) return Error("Invalid ALLOCA record");
+ I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
+ unsigned OpNum = 0;
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+ OpNum+2 != Record.size())
+ return Error("Invalid LOAD record");
+
+ I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_LOADATOMIC: {
+ // LOADATOMIC: [opty, op, align, vol, ordering, synchscope]
+ unsigned OpNum = 0;
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+ OpNum+4 != Record.size())
+ return Error("Invalid LOADATOMIC record");
+
+
+ AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+ if (Ordering == NotAtomic || Ordering == Release ||
+ Ordering == AcquireRelease)
+ return Error("Invalid LOADATOMIC record");
+ if (Ordering != NotAtomic && Record[OpNum] == 0)
+ return Error("Invalid LOADATOMIC record");
+ SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+
+ 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]
+ 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 STORE record");
+
+ I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_STOREATOMIC: {
+ // 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 STOREATOMIC record");
+
+ AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+ if (Ordering == NotAtomic || Ordering == Acquire ||
+ Ordering == AcquireRelease)
+ return Error("Invalid STOREATOMIC record");
+ SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+ if (Ordering != NotAtomic && Record[OpNum] == 0)
+ return Error("Invalid STOREATOMIC record");
+
+ I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1,
+ Ordering, SynchScope);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CMPXCHG: {
+ // CMPXCHG:[ptrty, ptr, cmp, new, vol, ordering, synchscope]
+ 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) ||
+ OpNum+3 != Record.size())
+ return Error("Invalid CMPXCHG record");
+ AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+1]);
+ if (Ordering == NotAtomic || Ordering == Unordered)
+ return Error("Invalid CMPXCHG record");
+ SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]);
+ I = new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope);
+ cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_ATOMICRMW: {
+ // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, synchscope]
+ unsigned OpNum = 0;
+ Value *Ptr, *Val;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+ popValue(Record, OpNum, NextValueNo,
+ cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+ OpNum+4 != Record.size())
+ return Error("Invalid ATOMICRMW record");
+ AtomicRMWInst::BinOp Operation = GetDecodedRMWOperation(Record[OpNum]);
+ if (Operation < AtomicRMWInst::FIRST_BINOP ||
+ Operation > AtomicRMWInst::LAST_BINOP)
+ return Error("Invalid ATOMICRMW record");
+ AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+ if (Ordering == NotAtomic || Ordering == Unordered)
+ return Error("Invalid ATOMICRMW 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);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope]
+ if (2 != Record.size())
+ return Error("Invalid FENCE record");
+ AtomicOrdering Ordering = GetDecodedOrdering(Record[0]);
+ if (Ordering == NotAtomic || Ordering == Unordered ||
+ Ordering == Monotonic)
+ return Error("Invalid FENCE record");
+ SynchronizationScope SynchScope = GetDecodedSynchScope(Record[1]);
+ I = new FenceInst(Context, Ordering, SynchScope);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CALL: {
+ // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...]
+ if (Record.size() < 3)
+ return Error("Invalid CALL record");
+
+ AttributeSet PAL = getAttributes(Record[0]);
+ unsigned CCInfo = Record[1];
+
+ unsigned OpNum = 2;
+ Value *Callee;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+ return Error("Invalid CALL record");
+
+ PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
+ FunctionType *FTy = 0;
+ if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
+ if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
+ return Error("Invalid CALL record");
+
+ SmallVector<Value*, 16> Args;
+ // Read the fixed params.
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+ if (FTy->getParamType(i)->isLabelTy())
+ Args.push_back(getBasicBlock(Record[OpNum]));
+ else
+ Args.push_back(getValue(Record, OpNum, NextValueNo,
+ FTy->getParamType(i)));
+ if (Args.back() == 0) return Error("Invalid CALL record");
+ }
+
+ // Read type/value pairs for varargs params.
+ if (!FTy->isVarArg()) {
+ if (OpNum != Record.size())
+ return Error("Invalid CALL record");
+ } else {
+ while (OpNum != Record.size()) {
+ Value *Op;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+ return Error("Invalid CALL record");
+ Args.push_back(Op);
+ }
+ }
+
+ I = CallInst::Create(Callee, Args);
+ InstructionList.push_back(I);
+ cast<CallInst>(I)->setCallingConv(
+ static_cast<CallingConv::ID>(CCInfo>>1));
+ cast<CallInst>(I)->setTailCall(CCInfo & 1);
+ cast<CallInst>(I)->setAttributes(PAL);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty]
+ if (Record.size() < 3)
+ return Error("Invalid VAARG 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 VAARG record");
+ I = new VAArgInst(Op, ResTy);
+ InstructionList.push_back(I);
+ break;
+ }
+ }
+
+ // Add instruction to end of current BB. If there is no current BB, reject
+ // this file.
+ if (CurBB == 0) {
+ delete I;
+ return Error("Invalid instruction with no BB");
+ }
+ CurBB->getInstList().push_back(I);
+
+ // If this was a terminator instruction, move to the next block.
+ if (isa<TerminatorInst>(I)) {
+ ++CurBBNo;
+ CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : 0;
+ }
+
+ // Non-void values get registered in the value table for future use.
+ if (I && !I->getType()->isVoidTy())
+ ValueList.AssignValue(I, NextValueNo++);
+ }
+
+OutOfRecordLoop:
+
+ // Check the function list for unresolved values.
+ if (Argument *A = dyn_cast<Argument>(ValueList.back())) {
+ if (A->getParent() == 0) {
+ // We found at least one unresolved value. Nuke them all to avoid leaks.
+ for (unsigned i = ModuleValueListSize, e = ValueList.size(); i != e; ++i){
+ if ((A = dyn_cast<Argument>(ValueList[i])) && A->getParent() == 0) {
+ A->replaceAllUsesWith(UndefValue::get(A->getType()));
+ delete A;
+ }
+ }
+ return Error("Never resolved value found in function!");
+ }
+ }
+
+ // FIXME: Check for unresolved forward-declared metadata references
+ // and clean up leaks.
+
+ // See if anything took the address of blocks in this function. If so,
+ // resolve them now.
+ DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
+ BlockAddrFwdRefs.find(F);
+ if (BAFRI != BlockAddrFwdRefs.end()) {
+ std::vector<BlockAddrRefTy> &RefList = BAFRI->second;
+ for (unsigned i = 0, e = RefList.size(); i != e; ++i) {
+ unsigned BlockIdx = RefList[i].first;
+ if (BlockIdx >= FunctionBBs.size())
+ return Error("Invalid blockaddress block #");
+
+ GlobalVariable *FwdRef = RefList[i].second;
+ FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
+ FwdRef->eraseFromParent();
+ }
+
+ BlockAddrFwdRefs.erase(BAFRI);
+ }
+
+ // Trim the value list down to the size it was before we parsed this function.
+ ValueList.shrinkTo(ModuleValueListSize);
+ MDValueList.shrinkTo(ModuleMDValueListSize);
+ std::vector<BasicBlock*>().swap(FunctionBBs);
+ return false;
+}
+
+/// FindFunctionInStream - Find the function body in the bitcode stream
+bool 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");
+ // ParseModule will parse the next body in the stream and set its
+ // position in the DeferredFunctionInfo map.
+ if (ParseModule(true)) return true;
+ }
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// GVMaterializer implementation
+//===----------------------------------------------------------------------===//
+
+
+bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
+ if (const Function *F = dyn_cast<Function>(GV)) {
+ return F->isDeclaration() &&
+ DeferredFunctionInfo.count(const_cast<Function*>(F));
+ }
+ return false;
+}
+
+bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) {
+ Function *F = dyn_cast<Function>(GV);
+ // If it's not a function or is already material, ignore the request.
+ if (!F || !F->isMaterializable()) return false;
+
+ DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
+ 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)
+ if (LazyStreamer && FindFunctionInStream(F, DFII)) return true;
+
+ // Move the bit stream to the saved position of the deferred function body.
+ Stream.JumpToBit(DFII->second);
+
+ if (ParseFunctionBody(F)) {
+ if (ErrInfo) *ErrInfo = ErrorString;
+ return true;
+ }
+
+ // Upgrade any old intrinsic calls in the function.
+ for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
+ E = UpgradedIntrinsics.end(); I != E; ++I) {
+ if (I->first != I->second) {
+ for (Value::use_iterator UI = I->first->use_begin(),
+ UE = I->first->use_end(); UI != UE; ) {
+ if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+ UpgradeIntrinsicCall(CI, I->second);
+ }
+ }
+ }
+
+ return false;
+}
+
+bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
+ const Function *F = dyn_cast<Function>(GV);
+ if (!F || F->isDeclaration())
+ return false;
+ return DeferredFunctionInfo.count(const_cast<Function*>(F));
+}
+
+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))
+ return;
+
+ assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+
+ // Just forget the function body, we can remat it later.
+ F->deleteBody();
+}
+
+
+bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
+ assert(M == TheModule &&
+ "Can only Materialize the Module this BitcodeReader is attached to.");
+ // Iterate over the module, deserializing any functions that are still on
+ // disk.
+ for (Module::iterator F = TheModule->begin(), E = TheModule->end();
+ F != E; ++F)
+ if (F->isMaterializable() &&
+ Materialize(F, ErrInfo))
+ return true;
+
+ // At this point, if there are any function bodies, the current bit is
+ // 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);
+
+ // 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
+ // module is materialized because there could always be another function body
+ // with calls to the old function.
+ for (std::vector<std::pair<Function*, Function*> >::iterator I =
+ UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) {
+ if (I->first != I->second) {
+ for (Value::use_iterator UI = I->first->use_begin(),
+ UE = I->first->use_end(); UI != UE; ) {
+ if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+ UpgradeIntrinsicCall(CI, I->second);
+ }
+ if (!I->first->use_empty())
+ I->first->replaceAllUsesWith(I->second);
+ I->first->eraseFromParent();
+ }
+ }
+ std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics);
+
+ return false;
+}
+
+bool BitcodeReader::InitStream() {
+ if (LazyStreamer) return InitLazyStream();
+ return InitStreamFromBuffer();
+}
+
+bool BitcodeReader::InitStreamFromBuffer() {
+ const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
+ const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+ if (Buffer->getBufferSize() & 3) {
+ if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
+ return Error("Invalid bitcode signature");
+ else
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+ }
+
+ // 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");
+
+ StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+ Stream.init(*StreamFile);
+
+ return false;
+}
+
+bool BitcodeReader::InitLazyStream() {
+ // Check and strip off the bitcode wrapper; BitstreamReader expects never to
+ // see it.
+ StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer);
+ StreamFile.reset(new BitstreamReader(Bytes));
+ Stream.init(*StreamFile);
+
+ unsigned char buf[16];
+ if (Bytes->readBytes(0, 16, buf, NULL) == -1)
+ return Error("Bitcode stream must be at least 16 bytes in length");
+
+ if (!isBitcode(buf, buf + 16))
+ return Error("Invalid bitcode signature");
+
+ if (isBitcodeWrapper(buf, buf + 4)) {
+ const unsigned char *bitcodeStart = buf;
+ const unsigned char *bitcodeEnd = buf + 16;
+ SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+ Bytes->dropLeadingBytes(bitcodeStart - buf);
+ Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart);
+ }
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// External interface
+//===----------------------------------------------------------------------===//
+
+/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
+///
+Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(Buffer->getBufferIdentifier(), Context);
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ delete M; // Also deletes R.
+ return 0;
+ }
+ // Have the BitcodeReader dtor delete 'Buffer'.
+ R->setBufferOwned(true);
+
+ R->materializeForwardReferencedFunctions();
+
+ return M;
+}
+
+
+Module *llvm::getStreamedBitcodeModule(const std::string &name,
+ DataStreamer *streamer,
+ LLVMContext &Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(name, Context);
+ BitcodeReader *R = new BitcodeReader(streamer, Context);
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+ delete M; // Also deletes R.
+ return 0;
+ }
+ R->setBufferOwned(false); // no buffer to delete
+ return M;
+}
+
+/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+/// If an error occurs, return null and fill in *ErrMsg if non-null.
+Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
+ std::string *ErrMsg){
+ Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg);
+ if (!M) return 0;
+
+ // Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether
+ // there was an error.
+ static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false);
+
+ // Read in the entire module, and destroy the BitcodeReader.
+ if (M->MaterializeAllPermanently(ErrMsg)) {
+ delete M;
+ return 0;
+ }
+
+ // 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 llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
+ // Don't let the BitcodeReader dtor delete 'Buffer'.
+ R->setBufferOwned(false);
+
+ std::string Triple("");
+ if (R->ParseTriple(Triple))
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ delete R;
+ return Triple;
+}
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h
new file mode 100644
index 0000000..28674eb
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.h
@@ -0,0 +1,349 @@
+//===- 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 BITCODE_READER_H
+#define BITCODE_READER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/GVMaterializer.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/ValueHandle.h"
+#include <vector>
+
+namespace llvm {
+ 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 {
+ std::vector<WeakVH> MDValuePtrs;
+
+ LLVMContext &Context;
+public:
+ BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {}
+
+ // vector compatibility methods
+ unsigned size() const { return MDValuePtrs.size(); }
+ void resize(unsigned N) { MDValuePtrs.resize(N); }
+ void push_back(Value *V) { MDValuePtrs.push_back(V); }
+ void clear() { MDValuePtrs.clear(); }
+ Value *back() const { return MDValuePtrs.back(); }
+ void pop_back() { MDValuePtrs.pop_back(); }
+ bool empty() const { return MDValuePtrs.empty(); }
+
+ Value *operator[](unsigned i) const {
+ assert(i < MDValuePtrs.size());
+ return MDValuePtrs[i];
+ }
+
+ void shrinkTo(unsigned N) {
+ assert(N <= size() && "Invalid shrinkTo request!");
+ MDValuePtrs.resize(N);
+ }
+
+ Value *getValueFwdRef(unsigned Idx);
+ void AssignValue(Value *V, unsigned Idx);
+};
+
+class BitcodeReader : public GVMaterializer {
+ LLVMContext &Context;
+ Module *TheModule;
+ MemoryBuffer *Buffer;
+ bool BufferOwned;
+ OwningPtr<BitstreamReader> StreamFile;
+ BitstreamCursor Stream;
+ DataStreamer *LazyStreamer;
+ uint64_t NextUnreadBit;
+ bool SeenValueSymbolTable;
+
+ const char *ErrorString;
+
+ std::vector<Type*> TypeList;
+ BitcodeReaderValueList ValueList;
+ BitcodeReaderMDValueList MDValueList;
+ SmallVector<Instruction *, 64> InstructionList;
+ SmallVector<SmallVector<uint64_t, 64>, 64> UseListRecords;
+
+ std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+ std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+
+ /// 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;
+
+ /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These
+ /// are resolved lazily when functions are loaded.
+ typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
+ DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
+
+ /// 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;
+
+public:
+ explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
+ : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false),
+ LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false),
+ ErrorString(0), ValueList(C), MDValueList(C),
+ SeenFirstFunctionBody(false), UseRelativeIDs(false) {
+ }
+ explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C)
+ : Context(C), TheModule(0), Buffer(0), BufferOwned(false),
+ LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false),
+ ErrorString(0), ValueList(C), MDValueList(C),
+ SeenFirstFunctionBody(false), UseRelativeIDs(false) {
+ }
+ ~BitcodeReader() {
+ FreeState();
+ }
+
+ void materializeForwardReferencedFunctions();
+
+ void FreeState();
+
+ /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
+ /// when the reader is destroyed.
+ void setBufferOwned(bool Owned) { BufferOwned = Owned; }
+
+ virtual bool isMaterializable(const GlobalValue *GV) const;
+ virtual bool isDematerializable(const GlobalValue *GV) const;
+ virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
+ virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0);
+ virtual void Dematerialize(GlobalValue *GV);
+
+ bool Error(const char *Str) {
+ ErrorString = Str;
+ return true;
+ }
+ const char *getErrorString() const { return ErrorString; }
+
+ /// @brief Main interface to parsing a bitcode buffer.
+ /// @returns true if an error occurred.
+ bool ParseBitcodeInto(Module *M);
+
+ /// @brief Cheap mechanism to just extract module triple
+ /// @returns true if an error occurred.
+ bool ParseTriple(std::string &Triple);
+
+ static uint64_t decodeSignRotatedValue(uint64_t V);
+
+private:
+ Type *getTypeByID(unsigned ID);
+ Value *getFnValueByID(unsigned ID, Type *Ty) {
+ if (Ty && Ty->isMetadataTy())
+ return MDValueList.getValueFwdRef(ID);
+ return ValueList.getValueFwdRef(ID, Ty);
+ }
+ BasicBlock *getBasicBlock(unsigned ID) const {
+ if (ID >= FunctionBBs.size()) return 0; // 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(SmallVector<uint64_t, 64> &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, 0);
+ return ResVal == 0;
+ } else if (Slot == Record.size()) {
+ return true;
+ }
+
+ unsigned TypeNo = (unsigned)Record[Slot++];
+ ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
+ return ResVal == 0;
+ }
+
+ /// 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(SmallVector<uint64_t, 64> &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(SmallVector<uint64_t, 64> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty, Value *&ResVal) {
+ ResVal = getValue(Record, Slot, InstNum, Ty);
+ return ResVal == 0;
+ }
+
+ /// getValue -- Version of getValue that returns ResVal directly,
+ /// or 0 if there is an error.
+ Value *getValue(SmallVector<uint64_t, 64> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty) {
+ if (Slot == Record.size()) return 0;
+ 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(SmallVector<uint64_t, 64> &Record, unsigned Slot,
+ unsigned InstNum, Type *Ty) {
+ if (Slot == Record.size()) return 0;
+ 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);
+ }
+
+ bool ParseModule(bool Resume);
+ bool ParseAttributeBlock();
+ bool ParseAttributeGroupBlock();
+ bool ParseTypeTable();
+ bool ParseTypeTableBody();
+
+ bool ParseValueSymbolTable();
+ bool ParseConstants();
+ bool RememberAndSkipFunctionBody();
+ bool ParseFunctionBody(Function *F);
+ bool GlobalCleanup();
+ bool ResolveGlobalAndAliasInits();
+ bool ParseMetadata();
+ bool ParseMetadataAttachment();
+ bool ParseModuleTriple(std::string &Triple);
+ bool ParseUseLists();
+ bool InitStream();
+ bool InitStreamFromBuffer();
+ bool InitLazyStream();
+ bool 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
new file mode 100644
index 0000000..9dafe2a
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp
@@ -0,0 +1,371 @@
+//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/BitstreamReader.h"
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// BitstreamCursor implementation
+//===----------------------------------------------------------------------===//
+
+void BitstreamCursor::operator=(const BitstreamCursor &RHS) {
+ freeState();
+
+ BitStream = RHS.BitStream;
+ NextChar = RHS.NextChar;
+ CurWord = RHS.CurWord;
+ BitsInCurWord = RHS.BitsInCurWord;
+ CurCodeSize = RHS.CurCodeSize;
+
+ // Copy abbreviations, and bump ref counts.
+ CurAbbrevs = RHS.CurAbbrevs;
+ for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i)
+ CurAbbrevs[i]->addRef();
+
+ // Copy block scope and bump ref counts.
+ BlockScope = RHS.BlockScope;
+ for (size_t S = 0, e = BlockScope.size(); S != e; ++S) {
+ std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
+ for (size_t i = 0, e = Abbrevs.size(); i != e; ++i)
+ Abbrevs[i]->addRef();
+ }
+}
+
+void BitstreamCursor::freeState() {
+ // Free all the Abbrevs.
+ for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+ CurAbbrevs.clear();
+
+ // Free all the Abbrevs in the block scope.
+ for (size_t S = 0, e = BlockScope.size(); S != e; ++S) {
+ std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
+ for (size_t i = 0, e = Abbrevs.size(); i != e; ++i)
+ Abbrevs[i]->dropRef();
+ }
+ BlockScope.clear();
+}
+
+/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
+/// the block, and return true if the block has an error.
+bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
+ // Save the current block's state on BlockScope.
+ BlockScope.push_back(Block(CurCodeSize));
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+ // Add the abbrevs specific to this block to the CurAbbrevs list.
+ if (const BitstreamReader::BlockInfo *Info =
+ BitStream->getBlockInfo(BlockID)) {
+ for (size_t i = 0, e = Info->Abbrevs.size(); i != e; ++i) {
+ CurAbbrevs.push_back(Info->Abbrevs[i]);
+ CurAbbrevs.back()->addRef();
+ }
+ }
+
+ // Get the codesize of this block.
+ CurCodeSize = ReadVBR(bitc::CodeLenWidth);
+ SkipToFourByteBoundary();
+ unsigned NumWords = Read(bitc::BlockSizeWidth);
+ if (NumWordsP) *NumWordsP = NumWords;
+
+ // Validate that this block is sane.
+ if (CurCodeSize == 0 || AtEndOfStream())
+ return true;
+
+ return false;
+}
+
+void BitstreamCursor::readAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals) {
+ assert(Op.isLiteral() && "Not a literal");
+ // If the abbrev specifies the literal value to use, use it.
+ Vals.push_back(Op.getLiteralValue());
+}
+
+void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals) {
+ assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");
+
+ // Decode the value as we are commanded.
+ switch (Op.getEncoding()) {
+ case BitCodeAbbrevOp::Array:
+ case BitCodeAbbrevOp::Blob:
+ assert(0 && "Should not reach here");
+ case BitCodeAbbrevOp::Fixed:
+ Vals.push_back(Read((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::VBR:
+ Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::Char6:
+ Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
+ break;
+ }
+}
+
+void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) {
+ assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");
+
+ // Decode the value as we are commanded.
+ switch (Op.getEncoding()) {
+ case BitCodeAbbrevOp::Array:
+ case BitCodeAbbrevOp::Blob:
+ assert(0 && "Should not reach here");
+ case BitCodeAbbrevOp::Fixed:
+ (void)Read((unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::VBR:
+ (void)ReadVBR64((unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::Char6:
+ (void)Read(6);
+ break;
+ }
+}
+
+
+
+/// skipRecord - Read the current record and discard it.
+void BitstreamCursor::skipRecord(unsigned AbbrevID) {
+ // Skip unabbreviated records by reading past their entries.
+ if (AbbrevID == bitc::UNABBREV_RECORD) {
+ unsigned Code = ReadVBR(6);
+ (void)Code;
+ unsigned NumElts = ReadVBR(6);
+ for (unsigned i = 0; i != NumElts; ++i)
+ (void)ReadVBR64(6);
+ return;
+ }
+
+ const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
+
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral())
+ continue;
+
+ if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
+ Op.getEncoding() != BitCodeAbbrevOp::Blob) {
+ skipAbbreviatedField(Op);
+ continue;
+ }
+
+ if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
+ // Array case. Read the number of elements as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+
+ // Get the element encoding.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // Read all the elements.
+ for (; NumElts; --NumElts)
+ skipAbbreviatedField(EltEnc);
+ continue;
+ }
+
+ assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
+ // Blob case. Read the number of bytes as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+ SkipToFourByteBoundary(); // 32-bit alignment
+
+ // Figure out where the end of this blob will be including tail padding.
+ size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;
+
+ // If this would read off the end of the bitcode file, just set the
+ // record to empty and return.
+ if (!canSkipToPos(NewEnd/8)) {
+ NextChar = BitStream->getBitcodeBytes().getExtent();
+ break;
+ }
+
+ // Skip over the blob.
+ JumpToBit(NewEnd);
+ }
+}
+
+unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
+ SmallVectorImpl<uint64_t> &Vals,
+ StringRef *Blob) {
+ if (AbbrevID == bitc::UNABBREV_RECORD) {
+ unsigned Code = ReadVBR(6);
+ unsigned NumElts = ReadVBR(6);
+ for (unsigned i = 0; i != NumElts; ++i)
+ Vals.push_back(ReadVBR64(6));
+ return Code;
+ }
+
+ const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
+
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral()) {
+ readAbbreviatedLiteral(Op, Vals);
+ continue;
+ }
+
+ if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
+ Op.getEncoding() != BitCodeAbbrevOp::Blob) {
+ readAbbreviatedField(Op, Vals);
+ continue;
+ }
+
+ if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
+ // Array case. Read the number of elements as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+
+ // Get the element encoding.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // Read all the elements.
+ for (; NumElts; --NumElts)
+ readAbbreviatedField(EltEnc, Vals);
+ continue;
+ }
+
+ assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
+ // Blob case. Read the number of bytes as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+ SkipToFourByteBoundary(); // 32-bit alignment
+
+ // Figure out where the end of this blob will be including tail padding.
+ size_t CurBitPos = GetCurrentBitNo();
+ size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;
+
+ // If this would read off the end of the bitcode file, just set the
+ // record to empty and return.
+ if (!canSkipToPos(NewEnd/8)) {
+ Vals.append(NumElts, 0);
+ NextChar = BitStream->getBitcodeBytes().getExtent();
+ break;
+ }
+
+ // Otherwise, inform the streamer that we need these bytes in memory.
+ const char *Ptr = (const char*)
+ BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts);
+
+ // If we can return a reference to the data, do so to avoid copying it.
+ if (Blob) {
+ *Blob = StringRef(Ptr, NumElts);
+ } else {
+ // Otherwise, unpack into Vals with zero extension.
+ for (; NumElts; --NumElts)
+ Vals.push_back((unsigned char)*Ptr++);
+ }
+ // Skip over tail padding.
+ JumpToBit(NewEnd);
+ }
+
+ unsigned Code = (unsigned)Vals[0];
+ Vals.erase(Vals.begin());
+ return Code;
+}
+
+
+void BitstreamCursor::ReadAbbrevRecord() {
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ unsigned NumOpInfo = ReadVBR(5);
+ for (unsigned i = 0; i != NumOpInfo; ++i) {
+ bool IsLiteral = Read(1) ? true : false;
+ if (IsLiteral) {
+ Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
+ continue;
+ }
+
+ BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
+ if (BitCodeAbbrevOp::hasEncodingData(E)) {
+ unsigned 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
+ // a slow path in Read() to have to handle reading zero bits.
+ if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
+ Data == 0) {
+ Abbv->Add(BitCodeAbbrevOp(0));
+ continue;
+ }
+
+ Abbv->Add(BitCodeAbbrevOp(E, Data));
+ } else
+ Abbv->Add(BitCodeAbbrevOp(E));
+ }
+ CurAbbrevs.push_back(Abbv);
+}
+
+bool BitstreamCursor::ReadBlockInfoBlock() {
+ // If this is the second stream to get to the block info block, skip it.
+ if (BitStream->hasBlockInfoRecords())
+ return SkipBlock();
+
+ if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
+
+ SmallVector<uint64_t, 64> Record;
+ BitstreamReader::BlockInfo *CurBlockInfo = 0;
+
+ // Read all the records for this module.
+ while (1) {
+ BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
+
+ switch (Entry.Kind) {
+ case llvm::BitstreamEntry::SubBlock: // Handled for us already.
+ case llvm::BitstreamEntry::Error:
+ return true;
+ case llvm::BitstreamEntry::EndBlock:
+ return false;
+ case llvm::BitstreamEntry::Record:
+ // The interesting case.
+ break;
+ }
+
+ // Read abbrev records, associate them with CurBID.
+ if (Entry.ID == bitc::DEFINE_ABBREV) {
+ if (!CurBlockInfo) return true;
+ ReadAbbrevRecord();
+
+ // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
+ // appropriate BlockInfo.
+ BitCodeAbbrev *Abbv = CurAbbrevs.back();
+ CurAbbrevs.pop_back();
+ CurBlockInfo->Abbrevs.push_back(Abbv);
+ continue;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (readRecord(Entry.ID, Record)) {
+ default: break; // Default behavior, ignore unknown content.
+ case bitc::BLOCKINFO_CODE_SETBID:
+ if (Record.size() < 1) return true;
+ CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
+ break;
+ case bitc::BLOCKINFO_CODE_BLOCKNAME: {
+ if (!CurBlockInfo) return true;
+ if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ std::string Name;
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ Name += (char)Record[i];
+ CurBlockInfo->Name = Name;
+ break;
+ }
+ case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
+ if (!CurBlockInfo) return true;
+ if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ std::string Name;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i)
+ Name += (char)Record[i];
+ CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
+ Name));
+ break;
+ }
+ }
+ }
+}
+
diff --git a/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp
new file mode 100644
index 0000000..9f51c35
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp
@@ -0,0 +1,39 @@
+//===-- BitWriter.cpp -----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/BitWriter.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+
+/*===-- Operations on modules ---------------------------------------------===*/
+
+int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {
+ std::string ErrorInfo;
+ raw_fd_ostream OS(Path, ErrorInfo, raw_fd_ostream::F_Binary);
+
+ if (!ErrorInfo.empty())
+ return -1;
+
+ WriteBitcodeToFile(unwrap(M), OS);
+ return 0;
+}
+
+int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+ int Unbuffered) {
+ raw_fd_ostream OS(FD, ShouldClose, Unbuffered);
+
+ WriteBitcodeToFile(unwrap(M), OS);
+ return 0;
+}
+
+int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) {
+ return LLVMWriteBitcodeToFD(M, FileHandle, true, false);
+}
diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
new file mode 100644
index 0000000..1b73f23
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -0,0 +1,2020 @@
+//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Bitcode writer implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "ValueEnumerator.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <map>
+using namespace llvm;
+
+static cl::opt<bool>
+EnablePreserveUseListOrdering("enable-bc-uselist-preserve",
+ cl::desc("Turn on experimental support for "
+ "use-list order preservation."),
+ cl::init(false), cl::Hidden);
+
+/// These are manifest constants used by the bitcode writer. They do not need to
+/// be kept in sync with the reader, but need to be consistent within this file.
+enum {
+ // VALUE_SYMTAB_BLOCK abbrev id's.
+ VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+ VST_ENTRY_7_ABBREV,
+ VST_ENTRY_6_ABBREV,
+ VST_BBENTRY_6_ABBREV,
+
+ // CONSTANTS_BLOCK abbrev id's.
+ CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+ CONSTANTS_INTEGER_ABBREV,
+ CONSTANTS_CE_CAST_Abbrev,
+ CONSTANTS_NULL_Abbrev,
+
+ // FUNCTION_BLOCK abbrev id's.
+ FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+ FUNCTION_INST_BINOP_ABBREV,
+ FUNCTION_INST_BINOP_FLAGS_ABBREV,
+ FUNCTION_INST_CAST_ABBREV,
+ FUNCTION_INST_RET_VOID_ABBREV,
+ FUNCTION_INST_RET_VAL_ABBREV,
+ FUNCTION_INST_UNREACHABLE_ABBREV,
+
+ // SwitchInst Magic
+ SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
+};
+
+static unsigned GetEncodedCastOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ default: llvm_unreachable("Unknown cast instruction!");
+ case Instruction::Trunc : return bitc::CAST_TRUNC;
+ case Instruction::ZExt : return bitc::CAST_ZEXT;
+ case Instruction::SExt : return bitc::CAST_SEXT;
+ case Instruction::FPToUI : return bitc::CAST_FPTOUI;
+ case Instruction::FPToSI : return bitc::CAST_FPTOSI;
+ case Instruction::UIToFP : return bitc::CAST_UITOFP;
+ case Instruction::SIToFP : return bitc::CAST_SITOFP;
+ case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
+ case Instruction::FPExt : return bitc::CAST_FPEXT;
+ case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
+ case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
+ case Instruction::BitCast : return bitc::CAST_BITCAST;
+ }
+}
+
+static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ default: llvm_unreachable("Unknown binary instruction!");
+ case Instruction::Add:
+ case Instruction::FAdd: return bitc::BINOP_ADD;
+ case Instruction::Sub:
+ case Instruction::FSub: return bitc::BINOP_SUB;
+ case Instruction::Mul:
+ case Instruction::FMul: return bitc::BINOP_MUL;
+ case Instruction::UDiv: return bitc::BINOP_UDIV;
+ case Instruction::FDiv:
+ case Instruction::SDiv: return bitc::BINOP_SDIV;
+ case Instruction::URem: return bitc::BINOP_UREM;
+ case Instruction::FRem:
+ case Instruction::SRem: return bitc::BINOP_SREM;
+ case Instruction::Shl: return bitc::BINOP_SHL;
+ case Instruction::LShr: return bitc::BINOP_LSHR;
+ case Instruction::AShr: return bitc::BINOP_ASHR;
+ case Instruction::And: return bitc::BINOP_AND;
+ case Instruction::Or: return bitc::BINOP_OR;
+ case Instruction::Xor: return bitc::BINOP_XOR;
+ }
+}
+
+static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
+ switch (Op) {
+ default: llvm_unreachable("Unknown RMW operation!");
+ case AtomicRMWInst::Xchg: return bitc::RMW_XCHG;
+ case AtomicRMWInst::Add: return bitc::RMW_ADD;
+ case AtomicRMWInst::Sub: return bitc::RMW_SUB;
+ case AtomicRMWInst::And: return bitc::RMW_AND;
+ case AtomicRMWInst::Nand: return bitc::RMW_NAND;
+ case AtomicRMWInst::Or: return bitc::RMW_OR;
+ case AtomicRMWInst::Xor: return bitc::RMW_XOR;
+ case AtomicRMWInst::Max: return bitc::RMW_MAX;
+ case AtomicRMWInst::Min: return bitc::RMW_MIN;
+ case AtomicRMWInst::UMax: return bitc::RMW_UMAX;
+ case AtomicRMWInst::UMin: return bitc::RMW_UMIN;
+ }
+}
+
+static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
+ switch (Ordering) {
+ case NotAtomic: return bitc::ORDERING_NOTATOMIC;
+ case Unordered: return bitc::ORDERING_UNORDERED;
+ case Monotonic: return bitc::ORDERING_MONOTONIC;
+ case Acquire: return bitc::ORDERING_ACQUIRE;
+ case Release: return bitc::ORDERING_RELEASE;
+ case AcquireRelease: return bitc::ORDERING_ACQREL;
+ case SequentiallyConsistent: return bitc::ORDERING_SEQCST;
+ }
+ llvm_unreachable("Invalid ordering");
+}
+
+static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) {
+ switch (SynchScope) {
+ case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD;
+ case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD;
+ }
+ llvm_unreachable("Invalid synch scope");
+}
+
+static void WriteStringRecord(unsigned Code, StringRef Str,
+ unsigned AbbrevToUse, BitstreamWriter &Stream) {
+ SmallVector<unsigned, 64> Vals;
+
+ // Code: [strchar x N]
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
+ AbbrevToUse = 0;
+ Vals.push_back(Str[i]);
+ }
+
+ // Emit the finished record.
+ Stream.EmitRecord(Code, Vals, AbbrevToUse);
+}
+
+static void WriteAttributeGroupTable(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups();
+ if (AttrGrps.empty()) return;
+
+ Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
+
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) {
+ AttributeSet AS = AttrGrps[i];
+ for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
+ AttributeSet A = AS.getSlotAttributes(i);
+
+ Record.push_back(VE.getAttributeGroupID(A));
+ Record.push_back(AS.getSlotIndex(i));
+
+ for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0);
+ I != E; ++I) {
+ Attribute Attr = *I;
+ if (Attr.isEnumAttribute()) {
+ Record.push_back(0);
+ Record.push_back(Attr.getKindAsEnum());
+ } else if (Attr.isAlignAttribute()) {
+ Record.push_back(1);
+ Record.push_back(Attr.getKindAsEnum());
+ Record.push_back(Attr.getValueAsInt());
+ } else {
+ StringRef Kind = Attr.getKindAsString();
+ StringRef Val = Attr.getValueAsString();
+
+ Record.push_back(Val.empty() ? 3 : 4);
+ Record.append(Kind.begin(), Kind.end());
+ Record.push_back(0);
+ if (!Val.empty()) {
+ Record.append(Val.begin(), Val.end());
+ Record.push_back(0);
+ }
+ }
+ }
+
+ Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
+ Record.clear();
+ }
+ }
+
+ Stream.ExitBlock();
+}
+
+static void WriteAttributeTable(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const std::vector<AttributeSet> &Attrs = VE.getAttributes();
+ if (Attrs.empty()) return;
+
+ Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
+
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+ const AttributeSet &A = Attrs[i];
+ for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i)
+ Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i)));
+
+ Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
+ Record.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+/// WriteTypeTable - Write out the type table for a module.
+static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
+ const ValueEnumerator::TypeList &TypeList = VE.getTypes();
+
+ 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);
+
+ // Abbrev for TYPE_CODE_POINTER.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+ Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
+ unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_FUNCTION.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+ unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_STRUCT_ANON.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+ unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_STRUCT_NAME.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+ unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_STRUCT_NAMED.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+ unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_ARRAY.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+ unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Emit an entry count so the reader can reserve space.
+ TypeVals.push_back(TypeList.size());
+ Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals);
+ TypeVals.clear();
+
+ // Loop over all of the types, emitting each in turn.
+ for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+ Type *T = TypeList[i];
+ int AbbrevToUse = 0;
+ unsigned Code = 0;
+
+ switch (T->getTypeID()) {
+ default: llvm_unreachable("Unknown type!");
+ case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
+ case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
+ case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
+ case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
+ case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
+ case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
+ case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
+ case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
+ case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
+ case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
+ case Type::IntegerTyID:
+ // INTEGER: [width]
+ Code = bitc::TYPE_CODE_INTEGER;
+ TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
+ break;
+ case Type::PointerTyID: {
+ PointerType *PTy = cast<PointerType>(T);
+ // POINTER: [pointee type, address space]
+ Code = bitc::TYPE_CODE_POINTER;
+ TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+ unsigned AddressSpace = PTy->getAddressSpace();
+ TypeVals.push_back(AddressSpace);
+ if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
+ break;
+ }
+ case Type::FunctionTyID: {
+ FunctionType *FT = cast<FunctionType>(T);
+ // FUNCTION: [isvararg, retty, paramty x N]
+ Code = bitc::TYPE_CODE_FUNCTION;
+ TypeVals.push_back(FT->isVarArg());
+ TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
+ for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
+ TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
+ AbbrevToUse = FunctionAbbrev;
+ break;
+ }
+ case Type::StructTyID: {
+ StructType *ST = cast<StructType>(T);
+ // STRUCT: [ispacked, eltty x N]
+ TypeVals.push_back(ST->isPacked());
+ // Output all of the element types.
+ for (StructType::element_iterator I = ST->element_begin(),
+ E = ST->element_end(); I != E; ++I)
+ TypeVals.push_back(VE.getTypeID(*I));
+
+ if (ST->isLiteral()) {
+ Code = bitc::TYPE_CODE_STRUCT_ANON;
+ AbbrevToUse = StructAnonAbbrev;
+ } else {
+ if (ST->isOpaque()) {
+ Code = bitc::TYPE_CODE_OPAQUE;
+ } else {
+ Code = bitc::TYPE_CODE_STRUCT_NAMED;
+ AbbrevToUse = StructNamedAbbrev;
+ }
+
+ // Emit the name if it is present.
+ if (!ST->getName().empty())
+ WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(),
+ StructNameAbbrev, Stream);
+ }
+ break;
+ }
+ case Type::ArrayTyID: {
+ ArrayType *AT = cast<ArrayType>(T);
+ // ARRAY: [numelts, eltty]
+ Code = bitc::TYPE_CODE_ARRAY;
+ TypeVals.push_back(AT->getNumElements());
+ TypeVals.push_back(VE.getTypeID(AT->getElementType()));
+ AbbrevToUse = ArrayAbbrev;
+ break;
+ }
+ case Type::VectorTyID: {
+ VectorType *VT = cast<VectorType>(T);
+ // VECTOR [numelts, eltty]
+ Code = bitc::TYPE_CODE_VECTOR;
+ TypeVals.push_back(VT->getNumElements());
+ TypeVals.push_back(VE.getTypeID(VT->getElementType()));
+ break;
+ }
+ }
+
+ // Emit the finished record.
+ Stream.EmitRecord(Code, TypeVals, AbbrevToUse);
+ TypeVals.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+static unsigned getEncodedLinkage(const GlobalValue *GV) {
+ switch (GV->getLinkage()) {
+ case GlobalValue::ExternalLinkage: return 0;
+ case GlobalValue::WeakAnyLinkage: return 1;
+ case GlobalValue::AppendingLinkage: return 2;
+ case GlobalValue::InternalLinkage: return 3;
+ case GlobalValue::LinkOnceAnyLinkage: return 4;
+ case GlobalValue::DLLImportLinkage: return 5;
+ case GlobalValue::DLLExportLinkage: return 6;
+ case GlobalValue::ExternalWeakLinkage: return 7;
+ case GlobalValue::CommonLinkage: return 8;
+ case GlobalValue::PrivateLinkage: return 9;
+ case GlobalValue::WeakODRLinkage: return 10;
+ case GlobalValue::LinkOnceODRLinkage: return 11;
+ case GlobalValue::AvailableExternallyLinkage: return 12;
+ case GlobalValue::LinkerPrivateLinkage: return 13;
+ case GlobalValue::LinkerPrivateWeakLinkage: return 14;
+ case GlobalValue::LinkOnceODRAutoHideLinkage: return 15;
+ }
+ llvm_unreachable("Invalid linkage");
+}
+
+static unsigned getEncodedVisibility(const GlobalValue *GV) {
+ switch (GV->getVisibility()) {
+ case GlobalValue::DefaultVisibility: return 0;
+ case GlobalValue::HiddenVisibility: return 1;
+ case GlobalValue::ProtectedVisibility: return 2;
+ }
+ llvm_unreachable("Invalid visibility");
+}
+
+static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) {
+ switch (GV->getThreadLocalMode()) {
+ case GlobalVariable::NotThreadLocal: return 0;
+ case GlobalVariable::GeneralDynamicTLSModel: return 1;
+ case GlobalVariable::LocalDynamicTLSModel: return 2;
+ case GlobalVariable::InitialExecTLSModel: return 3;
+ case GlobalVariable::LocalExecTLSModel: return 4;
+ }
+ llvm_unreachable("Invalid TLS model");
+}
+
+// Emit top-level description of module, including target triple, inline asm,
+// descriptors for global variables, and function prototype info.
+static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ // Emit various pieces of data attached to a module.
+ if (!M->getTargetTriple().empty())
+ WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
+ 0/*TODO*/, Stream);
+ if (!M->getDataLayout().empty())
+ WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout(),
+ 0/*TODO*/, Stream);
+ if (!M->getModuleInlineAsm().empty())
+ WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
+ 0/*TODO*/, Stream);
+
+ // Emit information about sections and GC, computing how many there are. Also
+ // compute the maximum alignment value.
+ std::map<std::string, unsigned> SectionMap;
+ std::map<std::string, unsigned> GCMap;
+ unsigned MaxAlignment = 0;
+ unsigned MaxGlobalType = 0;
+ for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
+ GV != E; ++GV) {
+ MaxAlignment = std::max(MaxAlignment, GV->getAlignment());
+ MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType()));
+ if (GV->hasSection()) {
+ // Give section names unique ID's.
+ unsigned &Entry = SectionMap[GV->getSection()];
+ if (!Entry) {
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(),
+ 0/*TODO*/, Stream);
+ Entry = SectionMap.size();
+ }
+ }
+ }
+ for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+ MaxAlignment = std::max(MaxAlignment, F->getAlignment());
+ if (F->hasSection()) {
+ // Give section names unique ID's.
+ unsigned &Entry = SectionMap[F->getSection()];
+ if (!Entry) {
+ WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(),
+ 0/*TODO*/, Stream);
+ Entry = SectionMap.size();
+ }
+ }
+ if (F->hasGC()) {
+ // Same for GC names.
+ unsigned &Entry = GCMap[F->getGC()];
+ if (!Entry) {
+ WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(),
+ 0/*TODO*/, Stream);
+ Entry = GCMap.size();
+ }
+ }
+ }
+
+ // Emit abbrev for globals, now that we know # sections and max alignment.
+ unsigned SimpleGVarAbbrev = 0;
+ if (!M->global_empty()) {
+ // Add an abbrev for common globals with no visibility or thread localness.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ 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(0));
+ else {
+ unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(MaxEncAlignment+1)));
+ }
+ if (SectionMap.empty()) // Section.
+ Abbv->Add(BitCodeAbbrevOp(0));
+ else
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(SectionMap.size()+1)));
+ // Don't bother emitting vis + thread local.
+ SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
+ }
+
+ // Emit the global variable information.
+ SmallVector<unsigned, 64> Vals;
+ for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end();
+ GV != E; ++GV) {
+ unsigned AbbrevToUse = 0;
+
+ // GLOBALVAR: [type, isconst, initid,
+ // linkage, alignment, section, visibility, threadlocal,
+ // unnamed_addr]
+ Vals.push_back(VE.getTypeID(GV->getType()));
+ Vals.push_back(GV->isConstant());
+ Vals.push_back(GV->isDeclaration() ? 0 :
+ (VE.getValueID(GV->getInitializer()) + 1));
+ Vals.push_back(getEncodedLinkage(GV));
+ Vals.push_back(Log2_32(GV->getAlignment())+1);
+ Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
+ if (GV->isThreadLocal() ||
+ GV->getVisibility() != GlobalValue::DefaultVisibility ||
+ GV->hasUnnamedAddr() || GV->isExternallyInitialized()) {
+ Vals.push_back(getEncodedVisibility(GV));
+ Vals.push_back(getEncodedThreadLocalMode(GV));
+ Vals.push_back(GV->hasUnnamedAddr());
+ Vals.push_back(GV->isExternallyInitialized());
+ } else {
+ AbbrevToUse = SimpleGVarAbbrev;
+ }
+
+ Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
+ Vals.clear();
+ }
+
+ // Emit the function proto information.
+ for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+ // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
+ // section, visibility, gc, unnamed_addr]
+ Vals.push_back(VE.getTypeID(F->getType()));
+ Vals.push_back(F->getCallingConv());
+ Vals.push_back(F->isDeclaration());
+ Vals.push_back(getEncodedLinkage(F));
+ Vals.push_back(VE.getAttributeID(F->getAttributes()));
+ Vals.push_back(Log2_32(F->getAlignment())+1);
+ Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
+ Vals.push_back(getEncodedVisibility(F));
+ Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
+ Vals.push_back(F->hasUnnamedAddr());
+
+ unsigned AbbrevToUse = 0;
+ Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
+ Vals.clear();
+ }
+
+ // Emit the alias information.
+ for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
+ AI != E; ++AI) {
+ // ALIAS: [alias type, aliasee val#, linkage, visibility]
+ Vals.push_back(VE.getTypeID(AI->getType()));
+ Vals.push_back(VE.getValueID(AI->getAliasee()));
+ Vals.push_back(getEncodedLinkage(AI));
+ Vals.push_back(getEncodedVisibility(AI));
+ unsigned AbbrevToUse = 0;
+ Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
+ Vals.clear();
+ }
+}
+
+static uint64_t GetOptimizationFlags(const Value *V) {
+ uint64_t Flags = 0;
+
+ if (const OverflowingBinaryOperator *OBO =
+ dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (OBO->hasNoSignedWrap())
+ Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
+ if (OBO->hasNoUnsignedWrap())
+ Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
+ } else if (const PossiblyExactOperator *PEO =
+ dyn_cast<PossiblyExactOperator>(V)) {
+ if (PEO->isExact())
+ Flags |= 1 << bitc::PEO_EXACT;
+ } else if (const FPMathOperator *FPMO =
+ dyn_cast<const FPMathOperator>(V)) {
+ if (FPMO->hasUnsafeAlgebra())
+ Flags |= FastMathFlags::UnsafeAlgebra;
+ if (FPMO->hasNoNaNs())
+ Flags |= FastMathFlags::NoNaNs;
+ if (FPMO->hasNoInfs())
+ Flags |= FastMathFlags::NoInfs;
+ if (FPMO->hasNoSignedZeros())
+ Flags |= FastMathFlags::NoSignedZeros;
+ if (FPMO->hasAllowReciprocal())
+ Flags |= FastMathFlags::AllowReciprocal;
+ }
+
+ return Flags;
+}
+
+static void WriteMDNode(const MDNode *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVector<uint64_t, 64> &Record) {
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ if (N->getOperand(i)) {
+ Record.push_back(VE.getTypeID(N->getOperand(i)->getType()));
+ Record.push_back(VE.getValueID(N->getOperand(i)));
+ } else {
+ Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext())));
+ Record.push_back(0);
+ }
+ }
+ unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE :
+ bitc::METADATA_NODE;
+ Stream.EmitRecord(MDCode, Record, 0);
+ Record.clear();
+}
+
+static void WriteModuleMetadata(const Module *M,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const ValueEnumerator::ValueList &Vals = VE.getMDValues();
+ bool StartedMetadataBlock = false;
+ unsigned MDSAbbrev = 0;
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+
+ if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
+ if (!N->isFunctionLocal() || !N->getFunction()) {
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+ WriteMDNode(N, VE, Stream, Record);
+ }
+ } else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) {
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+ // Abbrev for METADATA_STRING.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ MDSAbbrev = Stream.EmitAbbrev(Abbv);
+ StartedMetadataBlock = true;
+ }
+
+ // Code: [strchar x N]
+ Record.append(MDS->begin(), MDS->end());
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+ Record.clear();
+ }
+ }
+
+ // Write named metadata.
+ for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
+ E = M->named_metadata_end(); I != E; ++I) {
+ const NamedMDNode *NMD = I;
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+
+ // Write name.
+ StringRef Str = NMD->getName();
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ Record.push_back(Str[i]);
+ Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/);
+ Record.clear();
+
+ // Write named metadata operands.
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
+ Record.push_back(VE.getValueID(NMD->getOperand(i)));
+ Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
+ Record.clear();
+ }
+
+ if (StartedMetadataBlock)
+ Stream.ExitBlock();
+}
+
+static void WriteFunctionLocalMetadata(const Function &F,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ bool StartedMetadataBlock = false;
+ SmallVector<uint64_t, 64> Record;
+ const SmallVector<const MDNode *, 8> &Vals = VE.getFunctionLocalMDValues();
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i)
+ if (const MDNode *N = Vals[i])
+ if (N->isFunctionLocal() && N->getFunction() == &F) {
+ if (!StartedMetadataBlock) {
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+ StartedMetadataBlock = true;
+ }
+ WriteMDNode(N, VE, Stream, Record);
+ }
+
+ if (StartedMetadataBlock)
+ Stream.ExitBlock();
+}
+
+static void WriteMetadataAttachment(const Function &F,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Write metadata attachments
+ // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
+
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+ I != E; ++I) {
+ MDs.clear();
+ I->getAllMetadataOtherThanDebugLoc(MDs);
+
+ // If no metadata, ignore instruction.
+ if (MDs.empty()) continue;
+
+ Record.push_back(VE.getInstructionID(I));
+
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ Record.push_back(MDs[i].first);
+ Record.push_back(VE.getValueID(MDs[i].second));
+ }
+ Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+ Record.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
+ SmallVector<uint64_t, 64> Record;
+
+ // Write metadata kinds
+ // METADATA_KIND - [n x [id, name]]
+ SmallVector<StringRef, 8> Names;
+ M->getMDKindNames(Names);
+
+ if (Names.empty()) return;
+
+ Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+ for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
+ Record.push_back(MDKindID);
+ StringRef KName = Names[MDKindID];
+ Record.append(KName.begin(), KName.end());
+
+ Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
+ Record.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
+ if ((int64_t)V >= 0)
+ Vals.push_back(V << 1);
+ else
+ Vals.push_back((-V << 1) | 1);
+}
+
+static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals,
+ unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
+ bool EmitSizeForWideNumbers = false
+ ) {
+ if (Val.getBitWidth() <= 64) {
+ uint64_t V = Val.getSExtValue();
+ emitSignedInt64(Vals, V);
+ Code = bitc::CST_CODE_INTEGER;
+ AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+ } else {
+ // Wide integers, > 64 bits in size.
+ // We have an arbitrary precision integer value to write whose
+ // bit width is > 64. However, in canonical unsigned integer
+ // format it is likely that the high bits are going to be zero.
+ // So, we only write the number of active words.
+ unsigned NWords = Val.getActiveWords();
+
+ if (EmitSizeForWideNumbers)
+ Vals.push_back(NWords);
+
+ const uint64_t *RawWords = Val.getRawData();
+ for (unsigned i = 0; i != NWords; ++i) {
+ emitSignedInt64(Vals, RawWords[i]);
+ }
+ Code = bitc::CST_CODE_WIDE_INTEGER;
+ }
+}
+
+static void WriteConstants(unsigned FirstVal, unsigned LastVal,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream, bool isGlobal) {
+ if (FirstVal == LastVal) return;
+
+ Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4);
+
+ unsigned AggregateAbbrev = 0;
+ unsigned String8Abbrev = 0;
+ unsigned CString7Abbrev = 0;
+ unsigned CString6Abbrev = 0;
+ // If this is a constant pool for the module, emit module-specific abbrevs.
+ if (isGlobal) {
+ // Abbrev for CST_CODE_AGGREGATE.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1)));
+ AggregateAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for CST_CODE_STRING.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ String8Abbrev = Stream.EmitAbbrev(Abbv);
+ // Abbrev for CST_CODE_CSTRING.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+ CString7Abbrev = Stream.EmitAbbrev(Abbv);
+ // Abbrev for CST_CODE_CSTRING.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+ CString6Abbrev = Stream.EmitAbbrev(Abbv);
+ }
+
+ SmallVector<uint64_t, 64> Record;
+
+ const ValueEnumerator::ValueList &Vals = VE.getValues();
+ Type *LastTy = 0;
+ for (unsigned i = FirstVal; i != LastVal; ++i) {
+ const Value *V = Vals[i].first;
+ // If we need to switch types, do so now.
+ if (V->getType() != LastTy) {
+ LastTy = V->getType();
+ Record.push_back(VE.getTypeID(LastTy));
+ Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
+ CONSTANTS_SETTYPE_ABBREV);
+ Record.clear();
+ }
+
+ if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+ Record.push_back(unsigned(IA->hasSideEffects()) |
+ unsigned(IA->isAlignStack()) << 1 |
+ unsigned(IA->getDialect()&1) << 2);
+
+ // 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]);
+
+ // 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]);
+ Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
+ Record.clear();
+ continue;
+ }
+ const Constant *C = cast<Constant>(V);
+ unsigned Code = -1U;
+ unsigned AbbrevToUse = 0;
+ if (C->isNullValue()) {
+ Code = bitc::CST_CODE_NULL;
+ } else if (isa<UndefValue>(C)) {
+ Code = bitc::CST_CODE_UNDEF;
+ } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
+ EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
+ } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ Code = bitc::CST_CODE_FLOAT;
+ Type *Ty = CFP->getType();
+ if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) {
+ Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+ } else if (Ty->isX86_FP80Ty()) {
+ // api needed to prevent premature destruction
+ // bits are not in the same order as a normal i80 APInt, compensate.
+ APInt api = CFP->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = api.getRawData();
+ Record.push_back((p[1] << 48) | (p[0] >> 16));
+ Record.push_back(p[0] & 0xffffLL);
+ } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) {
+ APInt api = CFP->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = api.getRawData();
+ Record.push_back(p[0]);
+ Record.push_back(p[1]);
+ } else {
+ assert (0 && "Unknown FP type!");
+ }
+ } else if (isa<ConstantDataSequential>(C) &&
+ cast<ConstantDataSequential>(C)->isString()) {
+ const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
+ // Emit constant strings specially.
+ unsigned NumElts = Str->getNumElements();
+ // If this is a null-terminated string, use the denser CSTRING encoding.
+ if (Str->isCString()) {
+ Code = bitc::CST_CODE_CSTRING;
+ --NumElts; // Don't encode the null, which isn't allowed by char6.
+ } else {
+ Code = bitc::CST_CODE_STRING;
+ AbbrevToUse = String8Abbrev;
+ }
+ bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
+ bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
+ for (unsigned i = 0; i != NumElts; ++i) {
+ unsigned char V = Str->getElementAsInteger(i);
+ Record.push_back(V);
+ isCStr7 &= (V & 128) == 0;
+ if (isCStrChar6)
+ isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
+ }
+
+ if (isCStrChar6)
+ AbbrevToUse = CString6Abbrev;
+ else if (isCStr7)
+ AbbrevToUse = CString7Abbrev;
+ } else if (const ConstantDataSequential *CDS =
+ dyn_cast<ConstantDataSequential>(C)) {
+ Code = bitc::CST_CODE_DATA;
+ Type *EltTy = CDS->getType()->getElementType();
+ if (isa<IntegerType>(EltTy)) {
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+ Record.push_back(CDS->getElementAsInteger(i));
+ } else if (EltTy->isFloatTy()) {
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
+ union { float F; uint32_t I; };
+ F = CDS->getElementAsFloat(i);
+ Record.push_back(I);
+ }
+ } else {
+ assert(EltTy->isDoubleTy() && "Unknown ConstantData element type");
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
+ union { double F; uint64_t I; };
+ F = CDS->getElementAsDouble(i);
+ Record.push_back(I);
+ }
+ }
+ } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
+ isa<ConstantVector>(C)) {
+ Code = bitc::CST_CODE_AGGREGATE;
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+ Record.push_back(VE.getValueID(C->getOperand(i)));
+ AbbrevToUse = AggregateAbbrev;
+ } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ switch (CE->getOpcode()) {
+ default:
+ if (Instruction::isCast(CE->getOpcode())) {
+ Code = bitc::CST_CODE_CE_CAST;
+ Record.push_back(GetEncodedCastOpcode(CE->getOpcode()));
+ Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
+ } else {
+ assert(CE->getNumOperands() == 2 && "Unknown constant expr!");
+ Code = bitc::CST_CODE_CE_BINOP;
+ Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ uint64_t Flags = GetOptimizationFlags(CE);
+ if (Flags != 0)
+ Record.push_back(Flags);
+ }
+ break;
+ case Instruction::GetElementPtr:
+ Code = bitc::CST_CODE_CE_GEP;
+ if (cast<GEPOperator>(C)->isInBounds())
+ Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+ 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)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ Record.push_back(VE.getValueID(C->getOperand(2)));
+ break;
+ case Instruction::ExtractElement:
+ Code = bitc::CST_CODE_CE_EXTRACTELT;
+ Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ break;
+ case Instruction::InsertElement:
+ Code = bitc::CST_CODE_CE_INSERTELT;
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ Record.push_back(VE.getValueID(C->getOperand(2)));
+ break;
+ case Instruction::ShuffleVector:
+ // If the return type and argument types are the same, this is a
+ // standard shufflevector instruction. If the types are different,
+ // then the shuffle is widening or truncating the input vectors, and
+ // the argument type must also be encoded.
+ if (C->getType() == C->getOperand(0)->getType()) {
+ Code = bitc::CST_CODE_CE_SHUFFLEVEC;
+ } else {
+ Code = bitc::CST_CODE_CE_SHUFVEC_EX;
+ Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+ }
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ Record.push_back(VE.getValueID(C->getOperand(2)));
+ break;
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ Code = bitc::CST_CODE_CE_CMP;
+ Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+ Record.push_back(VE.getValueID(C->getOperand(0)));
+ Record.push_back(VE.getValueID(C->getOperand(1)));
+ Record.push_back(CE->getPredicate());
+ break;
+ }
+ } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+ Code = bitc::CST_CODE_BLOCKADDRESS;
+ Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+ Record.push_back(VE.getValueID(BA->getFunction()));
+ Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
+ } else {
+#ifndef NDEBUG
+ C->dump();
+#endif
+ llvm_unreachable("Unknown constant!");
+ }
+ Stream.EmitRecord(Code, Record, AbbrevToUse);
+ Record.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+static void WriteModuleConstants(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const ValueEnumerator::ValueList &Vals = VE.getValues();
+
+ // Find the first constant to emit, which is the first non-globalvalue value.
+ // We know globalvalues have been emitted by WriteModuleInfo.
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (!isa<GlobalValue>(Vals[i].first)) {
+ WriteConstants(i, Vals.size(), VE, Stream, true);
+ return;
+ }
+ }
+}
+
+/// PushValueAndType - The file has to encode both the value and type id for
+/// many values, because we need to know what type to create for forward
+/// references. However, most operands are not forward references, so this type
+/// field is not needed.
+///
+/// This function adds V's value ID to Vals. If the value ID is higher than the
+/// instruction ID, then it is a forward reference, and it also includes the
+/// type ID. The value ID that is written is encoded relative to the InstID.
+static bool PushValueAndType(const Value *V, unsigned InstID,
+ SmallVector<unsigned, 64> &Vals,
+ ValueEnumerator &VE) {
+ unsigned ValID = VE.getValueID(V);
+ // Make encoding relative to the InstID.
+ Vals.push_back(InstID - ValID);
+ if (ValID >= InstID) {
+ Vals.push_back(VE.getTypeID(V->getType()));
+ return true;
+ }
+ return false;
+}
+
+/// pushValue - Like PushValueAndType, but where the type of the value is
+/// omitted (perhaps it was already encoded in an earlier operand).
+static void pushValue(const Value *V, unsigned InstID,
+ SmallVector<unsigned, 64> &Vals,
+ ValueEnumerator &VE) {
+ unsigned ValID = VE.getValueID(V);
+ Vals.push_back(InstID - ValID);
+}
+
+static void pushValue64(const Value *V, unsigned InstID,
+ SmallVector<uint64_t, 128> &Vals,
+ ValueEnumerator &VE) {
+ uint64_t ValID = VE.getValueID(V);
+ Vals.push_back(InstID - ValID);
+}
+
+static void pushValueSigned(const Value *V, unsigned InstID,
+ SmallVector<uint64_t, 128> &Vals,
+ ValueEnumerator &VE) {
+ unsigned ValID = VE.getValueID(V);
+ int64_t diff = ((int32_t)InstID - (int32_t)ValID);
+ emitSignedInt64(Vals, diff);
+}
+
+/// WriteInstruction - Emit an instruction to the specified stream.
+static void WriteInstruction(const Instruction &I, unsigned InstID,
+ ValueEnumerator &VE, BitstreamWriter &Stream,
+ SmallVector<unsigned, 64> &Vals) {
+ unsigned Code = 0;
+ unsigned AbbrevToUse = 0;
+ VE.setInstructionID(&I);
+ switch (I.getOpcode()) {
+ default:
+ if (Instruction::isCast(I.getOpcode())) {
+ Code = bitc::FUNC_CODE_INST_CAST;
+ if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+ AbbrevToUse = FUNCTION_INST_CAST_ABBREV;
+ Vals.push_back(VE.getTypeID(I.getType()));
+ Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
+ } else {
+ assert(isa<BinaryOperator>(I) && "Unknown instruction!");
+ Code = bitc::FUNC_CODE_INST_BINOP;
+ if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+ AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
+ pushValue(I.getOperand(1), InstID, Vals, VE);
+ Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
+ uint64_t Flags = GetOptimizationFlags(&I);
+ if (Flags != 0) {
+ if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
+ AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
+ Vals.push_back(Flags);
+ }
+ }
+ break;
+
+ case Instruction::GetElementPtr:
+ Code = bitc::FUNC_CODE_INST_GEP;
+ if (cast<GEPOperator>(&I)->isInBounds())
+ Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
+ 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);
+ break;
+ }
+ case Instruction::InsertValue: {
+ Code = bitc::FUNC_CODE_INST_INSERTVAL;
+ 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);
+ break;
+ }
+ case Instruction::Select:
+ Code = bitc::FUNC_CODE_INST_VSELECT;
+ PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+ pushValue(I.getOperand(2), InstID, Vals, VE);
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ break;
+ case Instruction::ExtractElement:
+ Code = bitc::FUNC_CODE_INST_EXTRACTELT;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ pushValue(I.getOperand(1), InstID, Vals, VE);
+ break;
+ case Instruction::InsertElement:
+ Code = bitc::FUNC_CODE_INST_INSERTELT;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ pushValue(I.getOperand(1), InstID, Vals, VE);
+ pushValue(I.getOperand(2), InstID, Vals, VE);
+ break;
+ case Instruction::ShuffleVector:
+ Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ pushValue(I.getOperand(1), InstID, Vals, VE);
+ pushValue(I.getOperand(2), InstID, Vals, VE);
+ break;
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ // compare returning Int1Ty or vector of Int1Ty
+ Code = bitc::FUNC_CODE_INST_CMP2;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ pushValue(I.getOperand(1), InstID, Vals, VE);
+ Vals.push_back(cast<CmpInst>(I).getPredicate());
+ break;
+
+ case Instruction::Ret:
+ {
+ Code = bitc::FUNC_CODE_INST_RET;
+ unsigned NumOperands = I.getNumOperands();
+ if (NumOperands == 0)
+ AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV;
+ else if (NumOperands == 1) {
+ if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+ AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV;
+ } else {
+ for (unsigned i = 0, e = NumOperands; i != e; ++i)
+ PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+ }
+ }
+ break;
+ case Instruction::Br:
+ {
+ Code = bitc::FUNC_CODE_INST_BR;
+ const BranchInst &II = cast<BranchInst>(I);
+ Vals.push_back(VE.getValueID(II.getSuccessor(0)));
+ if (II.isConditional()) {
+ Vals.push_back(VE.getValueID(II.getSuccessor(1)));
+ pushValue(II.getCondition(), InstID, Vals, VE);
+ }
+ }
+ break;
+ case Instruction::Switch:
+ {
+ // Redefine Vals, since here we need to use 64 bit values
+ // explicitly to store large APInt numbers.
+ SmallVector<uint64_t, 128> Vals64;
+
+ Code = bitc::FUNC_CODE_INST_SWITCH;
+ const SwitchInst &SI = cast<SwitchInst>(I);
+
+ uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
+ Vals64.push_back(SwitchRecordHeader);
+
+ Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
+ pushValue64(SI.getCondition(), InstID, Vals64, VE);
+ Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
+ Vals64.push_back(SI.getNumCases());
+ for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
+ i != e; ++i) {
+ const IntegersSubset& CaseRanges = i.getCaseValueEx();
+ unsigned Code, Abbrev; // will unused.
+
+ if (CaseRanges.isSingleNumber()) {
+ Vals64.push_back(1/*NumItems = 1*/);
+ Vals64.push_back(true/*IsSingleNumber = true*/);
+ EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
+ } else {
+
+ Vals64.push_back(CaseRanges.getNumItems());
+
+ if (CaseRanges.isSingleNumbersOnly()) {
+ for (unsigned ri = 0, rn = CaseRanges.getNumItems();
+ ri != rn; ++ri) {
+
+ Vals64.push_back(true/*IsSingleNumber = true*/);
+
+ EmitAPInt(Vals64, Code, Abbrev,
+ CaseRanges.getSingleNumber(ri), true);
+ }
+ } else
+ for (unsigned ri = 0, rn = CaseRanges.getNumItems();
+ ri != rn; ++ri) {
+ IntegersSubset::Range r = CaseRanges.getItem(ri);
+ bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
+
+ Vals64.push_back(IsSingleNumber);
+
+ EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
+ if (!IsSingleNumber)
+ EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
+ }
+ }
+ Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
+ }
+
+ Stream.EmitRecord(Code, Vals64, AbbrevToUse);
+
+ // Also do expected action - clear external Vals collection:
+ Vals.clear();
+ return;
+ }
+ break;
+ case Instruction::IndirectBr:
+ Code = bitc::FUNC_CODE_INST_INDIRECTBR;
+ Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+ // Encode the address operand as relative, but not the basic blocks.
+ pushValue(I.getOperand(0), InstID, Vals, VE);
+ for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
+ Vals.push_back(VE.getValueID(I.getOperand(i)));
+ break;
+
+ 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());
+ Code = bitc::FUNC_CODE_INST_INVOKE;
+
+ Vals.push_back(VE.getAttributeID(II->getAttributes()));
+ Vals.push_back(II->getCallingConv());
+ Vals.push_back(VE.getValueID(II->getNormalDest()));
+ Vals.push_back(VE.getValueID(II->getUnwindDest()));
+ PushValueAndType(Callee, InstID, Vals, VE);
+
+ // Emit value #'s for the fixed parameters.
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+ pushValue(I.getOperand(i), InstID, Vals, VE); // fixed param.
+
+ // Emit type/value pairs for varargs params.
+ if (FTy->isVarArg()) {
+ for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3;
+ i != e; ++i)
+ PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg
+ }
+ break;
+ }
+ case Instruction::Resume:
+ Code = bitc::FUNC_CODE_INST_RESUME;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ break;
+ case Instruction::Unreachable:
+ Code = bitc::FUNC_CODE_INST_UNREACHABLE;
+ AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
+ break;
+
+ case Instruction::PHI: {
+ const PHINode &PN = cast<PHINode>(I);
+ Code = bitc::FUNC_CODE_INST_PHI;
+ // With the newer instruction encoding, forward references could give
+ // negative valued IDs. This is most common for PHIs, so we use
+ // signed VBRs.
+ SmallVector<uint64_t, 128> Vals64;
+ Vals64.push_back(VE.getTypeID(PN.getType()));
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+ pushValueSigned(PN.getIncomingValue(i), InstID, Vals64, VE);
+ Vals64.push_back(VE.getValueID(PN.getIncomingBlock(i)));
+ }
+ // Emit a Vals64 vector and exit.
+ Stream.EmitRecord(Code, Vals64, AbbrevToUse);
+ Vals64.clear();
+ return;
+ }
+
+ case Instruction::LandingPad: {
+ 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) {
+ if (LP.isCatch(I))
+ Vals.push_back(LandingPadInst::Catch);
+ else
+ Vals.push_back(LandingPadInst::Filter);
+ PushValueAndType(LP.getClause(I), InstID, Vals, VE);
+ }
+ break;
+ }
+
+ case Instruction::Alloca:
+ Code = bitc::FUNC_CODE_INST_ALLOCA;
+ Vals.push_back(VE.getTypeID(I.getType()));
+ Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+ Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
+ Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1);
+ break;
+
+ case Instruction::Load:
+ if (cast<LoadInst>(I).isAtomic()) {
+ Code = bitc::FUNC_CODE_INST_LOADATOMIC;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+ } else {
+ Code = bitc::FUNC_CODE_INST_LOAD;
+ if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr
+ AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
+ }
+ Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
+ Vals.push_back(cast<LoadInst>(I).isVolatile());
+ if (cast<LoadInst>(I).isAtomic()) {
+ Vals.push_back(GetEncodedOrdering(cast<LoadInst>(I).getOrdering()));
+ Vals.push_back(GetEncodedSynchScope(cast<LoadInst>(I).getSynchScope()));
+ }
+ break;
+ case Instruction::Store:
+ if (cast<StoreInst>(I).isAtomic())
+ Code = bitc::FUNC_CODE_INST_STOREATOMIC;
+ else
+ Code = bitc::FUNC_CODE_INST_STORE;
+ PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
+ pushValue(I.getOperand(0), InstID, Vals, VE); // val.
+ Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
+ Vals.push_back(cast<StoreInst>(I).isVolatile());
+ if (cast<StoreInst>(I).isAtomic()) {
+ Vals.push_back(GetEncodedOrdering(cast<StoreInst>(I).getOrdering()));
+ Vals.push_back(GetEncodedSynchScope(cast<StoreInst>(I).getSynchScope()));
+ }
+ break;
+ 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.
+ pushValue(I.getOperand(2), InstID, Vals, VE); // newval.
+ Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
+ Vals.push_back(GetEncodedOrdering(
+ cast<AtomicCmpXchgInst>(I).getOrdering()));
+ Vals.push_back(GetEncodedSynchScope(
+ cast<AtomicCmpXchgInst>(I).getSynchScope()));
+ break;
+ case Instruction::AtomicRMW:
+ Code = bitc::FUNC_CODE_INST_ATOMICRMW;
+ PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr
+ pushValue(I.getOperand(1), InstID, Vals, VE); // val.
+ Vals.push_back(GetEncodedRMWOperation(
+ cast<AtomicRMWInst>(I).getOperation()));
+ Vals.push_back(cast<AtomicRMWInst>(I).isVolatile());
+ Vals.push_back(GetEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering()));
+ Vals.push_back(GetEncodedSynchScope(
+ cast<AtomicRMWInst>(I).getSynchScope()));
+ break;
+ case Instruction::Fence:
+ Code = bitc::FUNC_CODE_INST_FENCE;
+ Vals.push_back(GetEncodedOrdering(cast<FenceInst>(I).getOrdering()));
+ Vals.push_back(GetEncodedSynchScope(cast<FenceInst>(I).getSynchScope()));
+ break;
+ case Instruction::Call: {
+ const CallInst &CI = cast<CallInst>(I);
+ PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
+ FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+ Code = bitc::FUNC_CODE_INST_CALL;
+
+ Vals.push_back(VE.getAttributeID(CI.getAttributes()));
+ Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()));
+ PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee
+
+ // Emit value #'s for the fixed parameters.
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
+ // Check for labels (can happen with asm labels).
+ if (FTy->getParamType(i)->isLabelTy())
+ Vals.push_back(VE.getValueID(CI.getArgOperand(i)));
+ else
+ pushValue(CI.getArgOperand(i), InstID, Vals, VE); // fixed param.
+ }
+
+ // Emit type/value pairs for varargs params.
+ if (FTy->isVarArg()) {
+ for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
+ i != e; ++i)
+ PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE); // varargs
+ }
+ break;
+ }
+ case Instruction::VAArg:
+ Code = bitc::FUNC_CODE_INST_VAARG;
+ Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); // valistty
+ pushValue(I.getOperand(0), InstID, Vals, VE); // valist.
+ Vals.push_back(VE.getTypeID(I.getType())); // restype.
+ break;
+ }
+
+ Stream.EmitRecord(Code, Vals, AbbrevToUse);
+ Vals.clear();
+}
+
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ if (VST.empty()) return;
+ Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
+
+ // FIXME: Set up the abbrev, we know how many values there are!
+ // FIXME: We know if the type names can use 7-bit ascii.
+ SmallVector<unsigned, 64> NameVals;
+
+ for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+ SI != SE; ++SI) {
+
+ const ValueName &Name = *SI;
+
+ // Figure out the encoding to use for the name.
+ bool is7Bit = true;
+ bool isChar6 = true;
+ for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength();
+ C != E; ++C) {
+ if (isChar6)
+ isChar6 = BitCodeAbbrevOp::isChar6(*C);
+ if ((unsigned char)*C & 128) {
+ is7Bit = false;
+ break; // don't bother scanning the rest.
+ }
+ }
+
+ unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
+
+ // VST_ENTRY: [valueid, namechar x N]
+ // VST_BBENTRY: [bbid, namechar x N]
+ unsigned Code;
+ if (isa<BasicBlock>(SI->getValue())) {
+ Code = bitc::VST_CODE_BBENTRY;
+ if (isChar6)
+ AbbrevToUse = VST_BBENTRY_6_ABBREV;
+ } else {
+ Code = bitc::VST_CODE_ENTRY;
+ if (isChar6)
+ AbbrevToUse = VST_ENTRY_6_ABBREV;
+ else if (is7Bit)
+ AbbrevToUse = VST_ENTRY_7_ABBREV;
+ }
+
+ NameVals.push_back(VE.getValueID(SI->getValue()));
+ for (const char *P = Name.getKeyData(),
+ *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P)
+ NameVals.push_back((unsigned char)*P);
+
+ // Emit the finished record.
+ Stream.EmitRecord(Code, NameVals, AbbrevToUse);
+ NameVals.clear();
+ }
+ Stream.ExitBlock();
+}
+
+/// WriteFunction - Emit a function body to the module stream.
+static void WriteFunction(const Function &F, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
+ VE.incorporateFunction(F);
+
+ SmallVector<unsigned, 64> Vals;
+
+ // Emit the number of basic blocks, so the reader can create them ahead of
+ // time.
+ Vals.push_back(VE.getBasicBlocks().size());
+ Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals);
+ Vals.clear();
+
+ // If there are function-local constants, emit them now.
+ unsigned CstStart, CstEnd;
+ VE.getFunctionConstantRange(CstStart, CstEnd);
+ WriteConstants(CstStart, CstEnd, VE, Stream, false);
+
+ // If there is function-local metadata, emit it now.
+ WriteFunctionLocalMetadata(F, VE, Stream);
+
+ // Keep a running idea of what the instruction ID is.
+ unsigned InstID = CstEnd;
+
+ bool NeedsMetadataAttachment = false;
+
+ DebugLoc LastDL;
+
+ // Finally, emit all the instructions, in order.
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+ I != E; ++I) {
+ WriteInstruction(*I, InstID, VE, Stream, Vals);
+
+ if (!I->getType()->isVoidTy())
+ ++InstID;
+
+ // If the instruction has metadata, write a metadata attachment later.
+ 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) {
+ // 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());
+
+ Vals.push_back(DL.getLine());
+ Vals.push_back(DL.getCol());
+ Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
+ Vals.push_back(IA ? VE.getValueID(IA)+1 : 0);
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+ Vals.clear();
+
+ LastDL = DL;
+ }
+ }
+
+ // Emit names for all the instructions etc.
+ WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
+
+ if (NeedsMetadataAttachment)
+ WriteMetadataAttachment(F, VE, Stream);
+ VE.purgeFunction();
+ Stream.ExitBlock();
+}
+
+// Emit blockinfo, which defines the standard abbreviations etc.
+static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
+ // We only want to emit block info records for blocks that have multiple
+ // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.
+ // Other blocks can define their abbrevs inline.
+ Stream.EnterBlockInfoBlock(2);
+
+ { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+ if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+ Abbv) != VST_ENTRY_8_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ { // 7-bit fixed width VST_ENTRY strings.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+ if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+ Abbv) != VST_ENTRY_7_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // 6-bit char6 VST_ENTRY strings.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+ if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+ Abbv) != VST_ENTRY_6_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // 6-bit char6 VST_BBENTRY strings.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+ if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+ Abbv) != VST_BBENTRY_6_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+
+
+ { // SETTYPE abbrev for CONSTANTS_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(VE.getTypes().size()+1)));
+ if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+ Abbv) != CONSTANTS_SETTYPE_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ { // INTEGER abbrev for CONSTANTS_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+ if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+ Abbv) != CONSTANTS_INTEGER_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ { // CE_CAST abbrev for CONSTANTS_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ 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)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id
+
+ if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+ Abbv) != CONSTANTS_CE_CAST_Abbrev)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // NULL abbrev for CONSTANTS_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL));
+ if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+ Abbv) != CONSTANTS_NULL_Abbrev)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ // FIXME: This should only use space for first class types!
+
+ { // INST_LOAD abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_LOAD_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // INST_BINOP abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_BINOP_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // INST_CAST abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ 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)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_CAST_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ { // INST_RET abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_RET_VOID_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // INST_RET abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_RET_VAL_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+ { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK.
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE));
+ if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+ Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
+ llvm_unreachable("Unexpected abbrev ordering!");
+ }
+
+ Stream.ExitBlock();
+}
+
+// Sort the Users based on the order in which the reader parses the bitcode
+// file.
+static bool bitcodereader_order(const User *lhs, const User *rhs) {
+ // TODO: Implement.
+ return true;
+}
+
+static void WriteUseList(const Value *V, const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+
+ // One or zero uses can't get out of order.
+ if (V->use_empty() || V->hasNUses(1))
+ return;
+
+ // Make a copy of the in-memory use-list for sorting.
+ unsigned UseListSize = std::distance(V->use_begin(), V->use_end());
+ SmallVector<const User*, 8> UseList;
+ UseList.reserve(UseListSize);
+ for (Value::const_use_iterator I = V->use_begin(), E = V->use_end();
+ I != E; ++I) {
+ const User *U = *I;
+ UseList.push_back(U);
+ }
+
+ // Sort the copy based on the order read by the BitcodeReader.
+ std::sort(UseList.begin(), UseList.end(), bitcodereader_order);
+
+ // TODO: Generate a diff between the BitcodeWriter in-memory use-list and the
+ // sorted list (i.e., the expected BitcodeReader in-memory use-list).
+
+ // TODO: Emit the USELIST_CODE_ENTRYs.
+}
+
+static void WriteFunctionUseList(const Function *F, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ VE.incorporateFunction(*F);
+
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI)
+ WriteUseList(AI, VE, Stream);
+ for (Function::const_iterator BB = F->begin(), FE = F->end(); BB != FE;
+ ++BB) {
+ WriteUseList(BB, VE, Stream);
+ for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
+ ++II) {
+ WriteUseList(II, VE, Stream);
+ for (User::const_op_iterator OI = II->op_begin(), E = II->op_end();
+ OI != E; ++OI) {
+ if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+ isa<InlineAsm>(*OI))
+ WriteUseList(*OI, VE, Stream);
+ }
+ }
+ }
+ VE.purgeFunction();
+}
+
+// Emit use-lists.
+static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
+
+ // XXX: this modifies the module, but in a way that should never change the
+ // behavior of any pass or codegen in LLVM. The problem is that GVs may
+ // contain entries in the use_list that do not exist in the Module and are
+ // not stored in the .bc file.
+ for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ I->removeDeadConstantUsers();
+
+ // Write the global variables.
+ for (Module::const_global_iterator GI = M->global_begin(),
+ GE = M->global_end(); GI != GE; ++GI) {
+ WriteUseList(GI, VE, Stream);
+
+ // Write the global variable initializers.
+ if (GI->hasInitializer())
+ WriteUseList(GI->getInitializer(), VE, Stream);
+ }
+
+ // Write the functions.
+ for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
+ WriteUseList(FI, VE, Stream);
+ if (!FI->isDeclaration())
+ WriteFunctionUseList(FI, VE, Stream);
+ }
+
+ // Write the aliases.
+ for (Module::const_alias_iterator AI = M->alias_begin(), AE = M->alias_end();
+ AI != AE; ++AI) {
+ WriteUseList(AI, VE, Stream);
+ WriteUseList(AI->getAliasee(), VE, Stream);
+ }
+
+ Stream.ExitBlock();
+}
+
+/// WriteModule - Emit the specified module to the bitstream.
+static void WriteModule(const Module *M, BitstreamWriter &Stream) {
+ Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
+
+ SmallVector<unsigned, 1> Vals;
+ unsigned CurVersion = 1;
+ Vals.push_back(CurVersion);
+ Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
+
+ // Analyze the module, enumerating globals, functions, etc.
+ ValueEnumerator VE(M);
+
+ // Emit blockinfo, which defines the standard abbreviations etc.
+ WriteBlockInfo(VE, Stream);
+
+ // Emit information about attribute groups.
+ WriteAttributeGroupTable(VE, Stream);
+
+ // Emit information about parameter attributes.
+ WriteAttributeTable(VE, Stream);
+
+ // Emit information describing all of the types in the module.
+ WriteTypeTable(VE, Stream);
+
+ // Emit top-level description of module, including target triple, inline asm,
+ // descriptors for global variables, and function prototype info.
+ WriteModuleInfo(M, VE, Stream);
+
+ // Emit constants.
+ WriteModuleConstants(VE, Stream);
+
+ // Emit metadata.
+ WriteModuleMetadata(M, VE, Stream);
+
+ // Emit metadata.
+ WriteModuleMetadataStore(M, Stream);
+
+ // Emit names for globals/functions etc.
+ WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
+
+ // Emit use-lists.
+ if (EnablePreserveUseListOrdering)
+ WriteModuleUseLists(M, VE, Stream);
+
+ // Emit function bodies.
+ for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
+ if (!F->isDeclaration())
+ WriteFunction(*F, VE, Stream);
+
+ Stream.ExitBlock();
+}
+
+/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a
+/// header and trailer to make it compatible with the system archiver. To do
+/// this we emit the following header, and then emit a trailer that pads the
+/// file out to be a multiple of 16 bytes.
+///
+/// struct bc_header {
+/// uint32_t Magic; // 0x0B17C0DE
+/// uint32_t Version; // Version, currently always 0.
+/// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+/// uint32_t BitcodeSize; // Size of traditional bitcode file.
+/// uint32_t CPUType; // CPU specifier.
+/// ... potentially more later ...
+/// };
+enum {
+ DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size.
+ DarwinBCHeaderSize = 5*4
+};
+
+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);
+ Position += 4;
+}
+
+static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
+ const Triple &TT) {
+ unsigned CPUType = ~0U;
+
+ // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+ // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+ // number from /usr/include/mach/machine.h. It is ok to reproduce the
+ // specific constants here because they are implicitly part of the Darwin ABI.
+ enum {
+ DARWIN_CPU_ARCH_ABI64 = 0x01000000,
+ DARWIN_CPU_TYPE_X86 = 7,
+ DARWIN_CPU_TYPE_ARM = 12,
+ DARWIN_CPU_TYPE_POWERPC = 18
+ };
+
+ Triple::ArchType Arch = TT.getArch();
+ if (Arch == Triple::x86_64)
+ CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
+ else if (Arch == Triple::x86)
+ CPUType = DARWIN_CPU_TYPE_X86;
+ else if (Arch == Triple::ppc)
+ CPUType = DARWIN_CPU_TYPE_POWERPC;
+ else if (Arch == Triple::ppc64)
+ CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+ else if (Arch == Triple::arm || Arch == Triple::thumb)
+ CPUType = DARWIN_CPU_TYPE_ARM;
+
+ // Traditional Bitcode starts after header.
+ assert(Buffer.size() >= DarwinBCHeaderSize &&
+ "Expected header size to be reserved");
+ unsigned BCOffset = DarwinBCHeaderSize;
+ unsigned BCSize = Buffer.size()-DarwinBCHeaderSize;
+
+ // Write the magic and version.
+ unsigned Position = 0;
+ WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
+ WriteInt32ToBuffer(0 , Buffer, Position); // Version.
+ WriteInt32ToBuffer(BCOffset , Buffer, Position);
+ WriteInt32ToBuffer(BCSize , Buffer, Position);
+ WriteInt32ToBuffer(CPUType , Buffer, Position);
+
+ // If the file is not a multiple of 16 bytes, insert dummy padding.
+ while (Buffer.size() & 15)
+ Buffer.push_back(0);
+}
+
+/// WriteBitcodeToFile - Write the specified module to the specified output
+/// stream.
+void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
+ SmallVector<char, 0> Buffer;
+ Buffer.reserve(256*1024);
+
+ // If this is darwin or another generic macho target, reserve space for the
+ // header.
+ Triple TT(M->getTargetTriple());
+ if (TT.isOSDarwin())
+ Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0);
+
+ // Emit the module into the buffer.
+ {
+ BitstreamWriter Stream(Buffer);
+
+ // Emit the file header.
+ Stream.Emit((unsigned)'B', 8);
+ Stream.Emit((unsigned)'C', 8);
+ Stream.Emit(0x0, 4);
+ Stream.Emit(0xC, 4);
+ Stream.Emit(0xE, 4);
+ Stream.Emit(0xD, 4);
+
+ // Emit the module.
+ WriteModule(M, Stream);
+ }
+
+ if (TT.isOSDarwin())
+ EmitDarwinBCHeaderAndTrailer(Buffer, TT);
+
+ // Write the generated bitstream to "Out".
+ Out.write((char*)&Buffer.front(), Buffer.size());
+}
diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
new file mode 100644
index 0000000..e5e76e2
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -0,0 +1,41 @@
+//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BitcodeWriterPass implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+namespace {
+ class WriteBitcodePass : public ModulePass {
+ raw_ostream &OS; // raw_ostream to print on
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ explicit WriteBitcodePass(raw_ostream &o)
+ : ModulePass(ID), OS(o) {}
+
+ const char *getPassName() const { return "Bitcode Writer"; }
+
+ bool runOnModule(Module &M) {
+ WriteBitcodeToFile(&M, OS);
+ return false;
+ }
+ };
+}
+
+char WriteBitcodePass::ID = 0;
+
+/// createBitcodeWriterPass - Create and return a pass that writes the module
+/// to the specified ostream.
+ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str) {
+ return new WriteBitcodePass(Str);
+}
diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
new file mode 100644
index 0000000..8bac6da
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -0,0 +1,540 @@
+//===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ValueEnumerator class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ValueEnumerator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+using namespace llvm;
+
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+ return V.first->getType()->isIntOrIntVectorTy();
+}
+
+/// ValueEnumerator - Enumerate module-level information.
+ValueEnumerator::ValueEnumerator(const Module *M) {
+ // Enumerate the global variables.
+ for (Module::const_global_iterator I = M->global_begin(),
+ E = M->global_end(); I != E; ++I)
+ EnumerateValue(I);
+
+ // Enumerate the functions.
+ for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ EnumerateValue(I);
+ EnumerateAttributes(cast<Function>(I)->getAttributes());
+ }
+
+ // Enumerate the aliases.
+ for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ I != E; ++I)
+ EnumerateValue(I);
+
+ // 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());
+
+ // Enumerate the aliasees.
+ for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+ I != E; ++I)
+ EnumerateValue(I->getAliasee());
+
+ // Insert constants and metadata that are named at module level into the slot
+ // pool so that the module symbol table can refer to them...
+ EnumerateValueSymbolTable(M->getValueSymbolTable());
+ EnumerateNamedMetadata(M);
+
+ SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+
+ // Enumerate types used by function bodies and argument lists.
+ for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
+
+ for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I)
+ EnumerateType(I->getType());
+
+ for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
+ for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+ OI != E; ++OI) {
+ if (MDNode *MD = dyn_cast<MDNode>(*OI))
+ if (MD->isFunctionLocal() && MD->getFunction())
+ // These will get enumerated during function-incorporation.
+ continue;
+ EnumerateOperandType(*OI);
+ }
+ EnumerateType(I->getType());
+ if (const CallInst *CI = dyn_cast<CallInst>(I))
+ EnumerateAttributes(CI->getAttributes());
+ else if (const InvokeInst *II = dyn_cast<InvokeInst>(I))
+ EnumerateAttributes(II->getAttributes());
+
+ // Enumerate metadata attached with this instruction.
+ MDs.clear();
+ I->getAllMetadataOtherThanDebugLoc(MDs);
+ 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);
+ }
+ }
+ }
+
+ // Optimize constant ordering.
+ OptimizeConstants(FirstConstant, Values.size());
+}
+
+unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
+ InstructionMapType::const_iterator I = InstructionMap.find(Inst);
+ assert(I != InstructionMap.end() && "Instruction is not mapped!");
+ return I->second;
+}
+
+void ValueEnumerator::setInstructionID(const Instruction *I) {
+ InstructionMap[I] = InstructionCount++;
+}
+
+unsigned ValueEnumerator::getValueID(const Value *V) const {
+ if (isa<MDNode>(V) || isa<MDString>(V)) {
+ ValueMapType::const_iterator I = MDValueMap.find(V);
+ assert(I != MDValueMap.end() && "Value not in slotcalculator!");
+ return I->second-1;
+ }
+
+ ValueMapType::const_iterator I = ValueMap.find(V);
+ assert(I != ValueMap.end() && "Value not in slotcalculator!");
+ return I->second-1;
+}
+
+void ValueEnumerator::dump() const {
+ print(dbgs(), ValueMap, "Default");
+ dbgs() << '\n';
+ print(dbgs(), MDValueMap, "MetaData");
+ dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (ValueMapType::const_iterator I = Map.begin(),
+ E = Map.end(); I != E; ++I) {
+
+ const Value *V = I->first;
+ if (V->hasName())
+ OS << "Value: " << V->getName();
+ else
+ OS << "Value: [null]\n";
+ V->dump();
+
+ OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+ for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE; ++UI) {
+ if (UI != V->use_begin())
+ OS << ",";
+ if((*UI)->hasName())
+ OS << " " << (*UI)->getName();
+ else
+ OS << " [null]";
+
+ }
+ OS << "\n\n";
+ }
+}
+
+// Optimize constant ordering.
+namespace {
+ struct CstSortPredicate {
+ ValueEnumerator &VE;
+ explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {}
+ bool operator()(const std::pair<const Value*, unsigned> &LHS,
+ const std::pair<const Value*, unsigned> &RHS) {
+ // Sort by plane.
+ if (LHS.first->getType() != RHS.first->getType())
+ return VE.getTypeID(LHS.first->getType()) <
+ VE.getTypeID(RHS.first->getType());
+ // Then by frequency.
+ return LHS.second > RHS.second;
+ }
+ };
+}
+
+/// OptimizeConstants - Reorder constant pool for denser encoding.
+void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
+ if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
+
+ CstSortPredicate P(*this);
+ std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
+
+ // Ensure that integer and vector of integer constants are at the start of the
+ // constant pool. This is important so that GEP structure indices come before
+ // gep constant exprs.
+ std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
+ isIntOrIntVectorValue);
+
+ // Rebuild the modified portion of ValueMap.
+ for (; CstStart != CstEnd; ++CstStart)
+ ValueMap[Values[CstStart].first] = CstStart+1;
+}
+
+
+/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
+/// table into the values table.
+void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
+ for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();
+ VI != VE; ++VI)
+ EnumerateValue(VI->getValue());
+}
+
+/// EnumerateNamedMetadata - Insert all of the values referenced by
+/// named metadata in the specified module.
+void ValueEnumerator::EnumerateNamedMetadata(const Module *M) {
+ for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
+ E = M->named_metadata_end(); I != E; ++I)
+ EnumerateNamedMDNode(I);
+}
+
+void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
+ for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
+ EnumerateMetadata(MD->getOperand(i));
+}
+
+/// EnumerateMDNodeOperands - Enumerate all non-function-local values
+/// and types referenced by the given MDNode.
+void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ if (Value *V = N->getOperand(i)) {
+ if (isa<MDNode>(V) || isa<MDString>(V))
+ EnumerateMetadata(V);
+ else if (!isa<Instruction>(V) && !isa<Argument>(V))
+ EnumerateValue(V);
+ } else
+ EnumerateType(Type::getVoidTy(N->getContext()));
+ }
+}
+
+void ValueEnumerator::EnumerateMetadata(const Value *MD) {
+ assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
+
+ // Enumerate the type of this value.
+ EnumerateType(MD->getType());
+
+ const MDNode *N = dyn_cast<MDNode>(MD);
+
+ // In the module-level pass, skip function-local nodes themselves, but
+ // do walk their operands.
+ if (N && N->isFunctionLocal() && N->getFunction()) {
+ EnumerateMDNodeOperands(N);
+ return;
+ }
+
+ // Check to see if it's already in!
+ unsigned &MDValueID = MDValueMap[MD];
+ if (MDValueID) {
+ // Increment use count.
+ MDValues[MDValueID-1].second++;
+ return;
+ }
+ MDValues.push_back(std::make_pair(MD, 1U));
+ MDValueID = MDValues.size();
+
+ // Enumerate all non-function-local operands.
+ if (N)
+ EnumerateMDNodeOperands(N);
+}
+
+/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
+/// information reachable from the given MDNode.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) {
+ assert(N->isFunctionLocal() && N->getFunction() &&
+ "EnumerateFunctionLocalMetadata called on non-function-local mdnode!");
+
+ // Enumerate the type of this value.
+ EnumerateType(N->getType());
+
+ // Check to see if it's already in!
+ unsigned &MDValueID = MDValueMap[N];
+ if (MDValueID) {
+ // Increment use count.
+ MDValues[MDValueID-1].second++;
+ return;
+ }
+ MDValues.push_back(std::make_pair(N, 1U));
+ MDValueID = MDValues.size();
+
+ // To incoroporate function-local information visit all function-local
+ // MDNodes and all function-local values they reference.
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ if (Value *V = N->getOperand(i)) {
+ if (MDNode *O = dyn_cast<MDNode>(V)) {
+ if (O->isFunctionLocal() && O->getFunction())
+ EnumerateFunctionLocalMetadata(O);
+ } else if (isa<Instruction>(V) || isa<Argument>(V))
+ EnumerateValue(V);
+ }
+
+ // Also, collect all function-local MDNodes for easy access.
+ FunctionLocalMDs.push_back(N);
+}
+
+void ValueEnumerator::EnumerateValue(const Value *V) {
+ assert(!V->getType()->isVoidTy() && "Can't insert void values!");
+ assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
+ "EnumerateValue doesn't handle Metadata!");
+
+ // Check to see if it's already in!
+ unsigned &ValueID = ValueMap[V];
+ if (ValueID) {
+ // Increment use count.
+ Values[ValueID-1].second++;
+ return;
+ }
+
+ // Enumerate the type of this value.
+ EnumerateType(V->getType());
+
+ if (const Constant *C = dyn_cast<Constant>(V)) {
+ if (isa<GlobalValue>(C)) {
+ // Initializers for globals are handled explicitly elsewhere.
+ } else if (C->getNumOperands()) {
+ // If a constant has operands, enumerate them. This makes sure that if a
+ // constant has uses (for example an array of const ints), that they are
+ // inserted also.
+
+ // We prefer to enumerate them with values before we enumerate the user
+ // itself. This makes it more likely that we can avoid forward references
+ // in the reader. We know that there can be no cycles in the constants
+ // graph that don't go through a global variable.
+ for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+ I != E; ++I)
+ if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
+ EnumerateValue(*I);
+
+ // Finally, add the value. Doing this could make the ValueID reference be
+ // dangling, don't reuse it.
+ Values.push_back(std::make_pair(V, 1U));
+ ValueMap[V] = Values.size();
+ return;
+ }
+ }
+
+ // Add the value.
+ Values.push_back(std::make_pair(V, 1U));
+ ValueID = Values.size();
+}
+
+
+void ValueEnumerator::EnumerateType(Type *Ty) {
+ unsigned *TypeID = &TypeMap[Ty];
+
+ // We've already seen this type.
+ if (*TypeID)
+ return;
+
+ // If it is a non-anonymous struct, mark the type as being visited so that we
+ // don't recursively visit it. This is safe because we allow forward
+ // references of these in the bitcode reader.
+ if (StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isLiteral())
+ *TypeID = ~0U;
+
+ // Enumerate all of the subtypes before we enumerate this type. This ensures
+ // that the type will be enumerated in an order that can be directly built.
+ for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+ I != E; ++I)
+ EnumerateType(*I);
+
+ // Refresh the TypeID pointer in case the table rehashed.
+ TypeID = &TypeMap[Ty];
+
+ // Check to see if we got the pointer another way. This can happen when
+ // enumerating recursive types that hit the base case deeper than they start.
+ //
+ // If this is actually a struct that we are treating as forward ref'able,
+ // then emit the definition now that all of its contents are available.
+ if (*TypeID && *TypeID != ~0U)
+ return;
+
+ // Add this type now that its contents are all happily enumerated.
+ Types.push_back(Ty);
+
+ *TypeID = Types.size();
+}
+
+// Enumerate the types for the specified value. If the value is a constant,
+// walk through it, enumerating the types of the constant.
+void ValueEnumerator::EnumerateOperandType(const Value *V) {
+ EnumerateType(V->getType());
+
+ if (const Constant *C = dyn_cast<Constant>(V)) {
+ // If this constant is already enumerated, ignore it, we know its type must
+ // be enumerated.
+ if (ValueMap.count(V)) return;
+
+ // This constant may have operands, make sure to enumerate the types in
+ // them.
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+ const Value *Op = C->getOperand(i);
+
+ // Don't enumerate basic blocks here, this happens as operands to
+ // blockaddress.
+ if (isa<BasicBlock>(Op)) continue;
+
+ EnumerateOperandType(Op);
+ }
+
+ if (const MDNode *N = dyn_cast<MDNode>(V)) {
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ if (Value *Elem = N->getOperand(i))
+ EnumerateOperandType(Elem);
+ }
+ } else if (isa<MDString>(V) || isa<MDNode>(V))
+ EnumerateMetadata(V);
+}
+
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
+ if (PAL.isEmpty()) return; // null is always 0.
+
+ // Do a lookup.
+ unsigned &Entry = AttributeMap[PAL];
+ if (Entry == 0) {
+ // Never saw this before, add it.
+ Attribute.push_back(PAL);
+ Entry = Attribute.size();
+ }
+
+ // Do lookups for all attribute groups.
+ for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+ AttributeSet AS = PAL.getSlotAttributes(i);
+ unsigned &Entry = AttributeGroupMap[AS];
+ if (Entry == 0) {
+ AttributeGroups.push_back(AS);
+ Entry = AttributeGroups.size();
+ }
+ }
+}
+
+void ValueEnumerator::incorporateFunction(const Function &F) {
+ InstructionCount = 0;
+ NumModuleValues = Values.size();
+ NumModuleMDValues = MDValues.size();
+
+ // Adding function arguments to the value table.
+ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
+ I != E; ++I)
+ EnumerateValue(I);
+
+ FirstFuncConstantID = Values.size();
+
+ // Add all function-level constants to the value table.
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
+ for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+ OI != E; ++OI) {
+ if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+ isa<InlineAsm>(*OI))
+ EnumerateValue(*OI);
+ }
+ BasicBlocks.push_back(BB);
+ ValueMap[BB] = BasicBlocks.size();
+ }
+
+ // Optimize the constant layout.
+ OptimizeConstants(FirstFuncConstantID, Values.size());
+
+ // Add the function's parameter attributes so they are available for use in
+ // the function's instruction.
+ EnumerateAttributes(F.getAttributes());
+
+ FirstInstID = Values.size();
+
+ SmallVector<MDNode *, 8> FnLocalMDVector;
+ // Add all of the instructions.
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
+ for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+ OI != E; ++OI) {
+ if (MDNode *MD = dyn_cast<MDNode>(*OI))
+ if (MD->isFunctionLocal() && MD->getFunction())
+ // Enumerate metadata after the instructions they might refer to.
+ FnLocalMDVector.push_back(MD);
+ }
+
+ SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
+ I->getAllMetadataOtherThanDebugLoc(MDs);
+ for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+ MDNode *N = MDs[i].second;
+ if (N->isFunctionLocal() && N->getFunction())
+ FnLocalMDVector.push_back(N);
+ }
+
+ if (!I->getType()->isVoidTy())
+ EnumerateValue(I);
+ }
+ }
+
+ // Add all of the function-local metadata.
+ for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i)
+ EnumerateFunctionLocalMetadata(FnLocalMDVector[i]);
+}
+
+void ValueEnumerator::purgeFunction() {
+ /// Remove purged values from the ValueMap.
+ for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
+ ValueMap.erase(Values[i].first);
+ for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i)
+ MDValueMap.erase(MDValues[i].first);
+ for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+ ValueMap.erase(BasicBlocks[i]);
+
+ Values.resize(NumModuleValues);
+ MDValues.resize(NumModuleMDValues);
+ BasicBlocks.clear();
+ FunctionLocalMDs.clear();
+}
+
+static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
+ DenseMap<const BasicBlock*, unsigned> &IDMap) {
+ unsigned Counter = 0;
+ for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ IDMap[BB] = ++Counter;
+}
+
+/// getGlobalBasicBlockID - This returns the function-specific ID for the
+/// specified basic block. This is relatively expensive information, so it
+/// should only be used by rare constructs such as address-of-label.
+unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
+ unsigned &Idx = GlobalBasicBlockIDs[BB];
+ if (Idx != 0)
+ return Idx-1;
+
+ IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
+ return getGlobalBasicBlockID(BB);
+}
+
diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h
new file mode 100644
index 0000000..0af6164c
--- /dev/null
+++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h
@@ -0,0 +1,171 @@
+//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class gives values and types Unique ID's.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VALUE_ENUMERATOR_H
+#define VALUE_ENUMERATOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include <vector>
+
+namespace llvm {
+
+class Type;
+class Value;
+class Instruction;
+class BasicBlock;
+class Function;
+class Module;
+class MDNode;
+class NamedMDNode;
+class AttributeSet;
+class ValueSymbolTable;
+class MDSymbolTable;
+class raw_ostream;
+
+class ValueEnumerator {
+public:
+ typedef std::vector<Type*> TypeList;
+
+ // For each value, we remember its Value* and occurrence frequency.
+ typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
+private:
+ typedef DenseMap<Type*, unsigned> TypeMapType;
+ TypeMapType TypeMap;
+ TypeList Types;
+
+ typedef DenseMap<const Value*, unsigned> ValueMapType;
+ ValueMapType ValueMap;
+ ValueList Values;
+ ValueList MDValues;
+ SmallVector<const MDNode *, 8> FunctionLocalMDs;
+ ValueMapType MDValueMap;
+
+ typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
+ AttributeGroupMapType AttributeGroupMap;
+ std::vector<AttributeSet> AttributeGroups;
+
+ typedef DenseMap<AttributeSet, unsigned> AttributeMapType;
+ AttributeMapType AttributeMap;
+ std::vector<AttributeSet> Attribute;
+
+ /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
+ /// the "getGlobalBasicBlockID" method.
+ mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs;
+
+ typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
+ InstructionMapType InstructionMap;
+ unsigned InstructionCount;
+
+ /// BasicBlocks - This contains all the basic blocks for the currently
+ /// incorporated function. Their reverse mapping is stored in ValueMap.
+ std::vector<const BasicBlock*> BasicBlocks;
+
+ /// When a function is incorporated, this is the size of the Values list
+ /// before incorporation.
+ unsigned NumModuleValues;
+
+ /// When a function is incorporated, this is the size of the MDValues list
+ /// before incorporation.
+ unsigned NumModuleMDValues;
+
+ unsigned FirstFuncConstantID;
+ unsigned FirstInstID;
+
+ ValueEnumerator(const ValueEnumerator &) LLVM_DELETED_FUNCTION;
+ void operator=(const ValueEnumerator &) LLVM_DELETED_FUNCTION;
+public:
+ ValueEnumerator(const Module *M);
+
+ void dump() const;
+ void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+
+ unsigned getValueID(const Value *V) const;
+
+ unsigned getTypeID(Type *T) const {
+ TypeMapType::const_iterator I = TypeMap.find(T);
+ assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
+ return I->second-1;
+ }
+
+ unsigned getInstructionID(const Instruction *I) const;
+ void setInstructionID(const Instruction *I);
+
+ unsigned getAttributeID(AttributeSet PAL) const {
+ if (PAL.isEmpty()) return 0; // Null maps to zero.
+ AttributeMapType::const_iterator I = AttributeMap.find(PAL);
+ assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
+ return I->second;
+ }
+
+ unsigned getAttributeGroupID(AttributeSet PAL) const {
+ if (PAL.isEmpty()) return 0; // Null maps to zero.
+ AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+ assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
+ return I->second;
+ }
+
+ /// getFunctionConstantRange - Return the range of values that corresponds to
+ /// function-local constants.
+ void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
+ Start = FirstFuncConstantID;
+ End = FirstInstID;
+ }
+
+ const ValueList &getValues() const { return Values; }
+ const ValueList &getMDValues() const { return MDValues; }
+ const SmallVector<const MDNode *, 8> &getFunctionLocalMDValues() const {
+ return FunctionLocalMDs;
+ }
+ const TypeList &getTypes() const { return Types; }
+ const std::vector<const BasicBlock*> &getBasicBlocks() const {
+ return BasicBlocks;
+ }
+ const std::vector<AttributeSet> &getAttributes() const {
+ return Attribute;
+ }
+ const std::vector<AttributeSet> &getAttributeGroups() const {
+ return AttributeGroups;
+ }
+
+ /// getGlobalBasicBlockID - This returns the function-specific ID for the
+ /// specified basic block. This is relatively expensive information, so it
+ /// should only be used by rare constructs such as address-of-label.
+ unsigned getGlobalBasicBlockID(const BasicBlock *BB) const;
+
+ /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
+ /// use these two methods to get its data into the ValueEnumerator!
+ ///
+ void incorporateFunction(const Function &F);
+ void purgeFunction();
+
+private:
+ void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
+
+ void EnumerateMDNodeOperands(const MDNode *N);
+ void EnumerateMetadata(const Value *MD);
+ void EnumerateFunctionLocalMetadata(const MDNode *N);
+ void EnumerateNamedMDNode(const NamedMDNode *NMD);
+ void EnumerateValue(const Value *V);
+ void EnumerateType(Type *T);
+ void EnumerateOperandType(const Value *V);
+ void EnumerateAttributes(AttributeSet PAL);
+
+ void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
+ void EnumerateNamedMetadata(const Module *M);
+};
+
+} // End llvm namespace
+
+#endif
OpenPOWER on IntegriCloud