X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.cpp;h=66ccdc2f90d195a45c3dce35476093a646cd37af;hb=21cc4460efa104e8591b05a90f20130291614344;hp=487a135509c40ada0322250721d8ce57212a64ec;hpb=d9d99ff8e8fe2897a3d45609763aeb8088b63afa;p=oota-llvm.git diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 487a135509c..66ccdc2f90d 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -18,11 +18,12 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/ParamAttrsList.h" #include "llvm/AutoUpgrade.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/OperandTraits.h" using namespace llvm; void BitcodeReader::FreeState() { @@ -30,7 +31,8 @@ void BitcodeReader::FreeState() { Buffer = 0; std::vector().swap(TypeList); ValueList.clear(); - std::vector().swap(ParamAttrs); + + std::vector().swap(MAttributes); std::vector().swap(FunctionBBs); std::vector().swap(FunctionsWithBodies); DeferredFunctionInfo.clear(); @@ -57,13 +59,17 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) { switch (Val) { default: // Map unknown/new linkages to external case 0: return GlobalValue::ExternalLinkage; - case 1: return GlobalValue::WeakLinkage; + case 1: return GlobalValue::WeakAnyLinkage; case 2: return GlobalValue::AppendingLinkage; case 3: return GlobalValue::InternalLinkage; - case 4: return GlobalValue::LinkOnceLinkage; + 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; } } @@ -114,7 +120,7 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) { } } - +namespace llvm { namespace { /// @brief A class for maintaining the slot number definition /// as a placeholder for the actual definition for forward constants defs. @@ -122,43 +128,85 @@ namespace { ConstantPlaceHolder(); // DO NOT IMPLEMENT void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT public: - Use Op; + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } explicit ConstantPlaceHolder(const Type *Ty) - : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1), - Op(UndefValue::get(Type::Int32Ty), this) { + : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) { + Op<0>() = UndefValue::get(Type::Int32Ty); + } + + /// @brief Methods to support type inquiry through isa, cast, and dyn_cast. + static inline bool classof(const ConstantPlaceHolder *) { return true; } + static bool classof(const Value *V) { + return isa(V) && + cast(V)->getOpcode() == Instruction::UserOp1; } + + + /// Provide fast operand accessors + //DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); }; } +// FIXME: can we inherit this from ConstantExpr? +template <> +struct OperandTraits : FixedNumOperandTraits<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(&*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, const Type *Ty) { - if (Idx >= size()) { - // Insert a bunch of null values. - Uses.resize(Idx+1); - OperandList = &Uses[0]; - NumOperands = Idx+1; - } + if (Idx >= size()) + resize(Idx + 1); - if (Value *V = Uses[Idx]) { + if (Value *V = ValuePtrs[Idx]) { assert(Ty == V->getType() && "Type mismatch in constant table!"); return cast(V); } // Create and return a placeholder, which will later be RAUW'd. Constant *C = new ConstantPlaceHolder(Ty); - Uses[Idx].init(C, this); + ValuePtrs[Idx] = C; return C; } Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { - if (Idx >= size()) { - // Insert a bunch of null values. - Uses.resize(Idx+1); - OperandList = &Uses[0]; - NumOperands = Idx+1; - } + if (Idx >= size()) + resize(Idx + 1); - if (Value *V = Uses[Idx]) { + if (Value *V = ValuePtrs[Idx]) { assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!"); return V; } @@ -168,10 +216,93 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { // Create and return a placeholder, which will later be RAUW'd. Value *V = new Argument(Ty); - Uses[Idx].init(V, this); + 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 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(); + + // If the using object isn't uniqued, just update the operands. This + // handles instructions and initializers for global variables. + if (!isa(*UI) || isa(*UI)) { + 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(*UI); + for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end(); + I != E; ++I) { + Value *NewOp; + if (!isa(*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(cast(*I), + 0)); + assert(It != ResolveConstants.end() && It->first == *I); + NewOp = operator[](It->second); + } + + NewOps.push_back(cast(NewOp)); + } + + // Make the new constant. + Constant *NewC; + if (ConstantArray *UserCA = dyn_cast(UserC)) { + NewC = ConstantArray::get(UserCA->getType(), &NewOps[0], NewOps.size()); + } else if (ConstantStruct *UserCS = dyn_cast(UserC)) { + NewC = ConstantStruct::get(&NewOps[0], NewOps.size(), + UserCS->getType()->isPacked()); + } else if (isa(UserC)) { + NewC = ConstantVector::get(&NewOps[0], NewOps.size()); + } else if (isa(UserC)) { + NewC = cast(UserC)->getWithOperands(&NewOps[0], + NewOps.size()); + } else { + assert(isa(UserC) && "Must be a metadata node."); + NewC = MDNode::get(&NewOps[0], NewOps.size()); + } + + UserC->replaceAllUsesWith(NewC); + UserC->destroyConstant(); + NewOps.clear(); + } + + delete Placeholder; + } +} + const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { // If the TypeID is in range, return it. @@ -190,16 +321,16 @@ const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { // Functions for parsing blocks from the bitcode file //===----------------------------------------------------------------------===// -bool BitcodeReader::ParseParamAttrBlock() { +bool BitcodeReader::ParseAttributeBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) return Error("Malformed block record"); - if (!ParamAttrs.empty()) + if (!MAttributes.empty()) return Error("Multiple PARAMATTR blocks found!"); SmallVector Record; - ParamAttrsVector Attrs; + SmallVector Attrs; // Read all the records. while (1) { @@ -232,11 +363,59 @@ bool BitcodeReader::ParseParamAttrBlock() { if (Record.size() & 1) return Error("Invalid ENTRY record"); + // FIXME : Remove this autoupgrade code in LLVM 3.0. + // If Function attributes are using index 0 then transfer them + // to index ~0. Index 0 is used for return value attributes but used to be + // used for function attributes. + Attributes RetAttribute = Attribute::None; + Attributes FnAttribute = Attribute::None; for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - if (Record[i+1] != ParamAttr::None) - Attrs.push_back(ParamAttrsWithIndex::get(Record[i], Record[i+1])); + // FIXME: remove in LLVM 3.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 = (Record[i+1] & (0xffffull << 16)) >> 16; + if (Alignment && !isPowerOf2_32(Alignment)) + return Error("Alignment is not a power of two."); + + Attributes ReconstitutedAttr = Record[i+1] & 0xffff; + if (Alignment) + ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment); + ReconstitutedAttr |= (Record[i+1] & (0xffffull << 32)) >> 11; + Record[i+1] = ReconstitutedAttr; + + if (Record[i] == 0) + RetAttribute = Record[i+1]; + else if (Record[i] == ~0U) + FnAttribute = Record[i+1]; } - ParamAttrs.push_back(Attrs.empty() ? NULL : ParamAttrsList::get(Attrs)); + + unsigned OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn| + Attribute::ReadOnly|Attribute::ReadNone); + + if (FnAttribute == Attribute::None && RetAttribute != Attribute::None && + (RetAttribute & OldRetAttrs) != 0) { + if (FnAttribute == Attribute::None) { // add a slot so they get added. + Record.push_back(~0U); + Record.push_back(0); + } + + FnAttribute |= RetAttribute & OldRetAttrs; + RetAttribute &= ~OldRetAttrs; + } + + for (unsigned i = 0, e = Record.size(); i != e; i += 2) { + if (Record[i] == 0) { + if (RetAttribute != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(0, RetAttribute)); + } else if (Record[i] == ~0U) { + if (FnAttribute != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute)); + } else if (Record[i+1] != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1])); + } + + MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end())); Attrs.clear(); break; } @@ -568,14 +747,8 @@ bool BitcodeReader::ParseConstants() { unsigned NextCstNo = ValueList.size(); while (1) { unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (NextCstNo != ValueList.size()) - return Error("Invalid constant reference!"); - - if (Stream.ReadBlockEnd()) - return Error("Error at end of constants block"); - return false; - } + if (Code == bitc::END_BLOCK) + break; if (Code == bitc::ENTER_SUBBLOCK) { // No known subblocks, always skip them. @@ -630,15 +803,19 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid FLOAT record"); if (CurTy == Type::FloatTy) - V = ConstantFP::get(CurTy, APFloat(APInt(32, (uint32_t)Record[0]))); + V = ConstantFP::get(APFloat(APInt(32, (uint32_t)Record[0]))); else if (CurTy == Type::DoubleTy) - V = ConstantFP::get(CurTy, APFloat(APInt(64, Record[0]))); - else if (CurTy == Type::X86_FP80Ty) - V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0]))); - else if (CurTy == Type::FP128Ty) - V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]), true)); + V = ConstantFP::get(APFloat(APInt(64, Record[0]))); + else if (CurTy == Type::X86_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(APFloat(APInt(80, 2, Rearrange))); + } else if (CurTy == Type::FP128Ty) + V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0]), true)); else if (CurTy == Type::PPC_FP128Ty) - V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]))); + V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0]))); else V = UndefValue::get(CurTy); break; @@ -749,8 +926,7 @@ bool BitcodeReader::ParseConstants() { dyn_cast_or_null(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], - OpTy->getElementType()); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::Int32Ty); V = ConstantExpr::getExtractElement(Op0, Op1); break; } @@ -768,7 +944,7 @@ bool BitcodeReader::ParseConstants() { case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval] const VectorType *OpTy = dyn_cast(CurTy); if (Record.size() < 3 || OpTy == 0) - return Error("Invalid CE_INSERTELT record"); + return Error("Invalid CE_SHUFFLEVEC record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy); const Type *ShufTy=VectorType::get(Type::Int32Ty, OpTy->getNumElements()); @@ -776,6 +952,18 @@ bool BitcodeReader::ParseConstants() { V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); break; } + case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval] + const VectorType *RTy = dyn_cast(CurTy); + const VectorType *OpTy = dyn_cast(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); + const Type *ShufTy=VectorType::get(Type::Int32Ty, 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"); const Type *OpTy = getTypeByID(Record[0]); @@ -785,8 +973,12 @@ bool BitcodeReader::ParseConstants() { if (OpTy->isFloatingPoint()) V = ConstantExpr::getFCmp(Record[3], Op0, Op1); - else + else if (!isa(OpTy)) V = ConstantExpr::getICmp(Record[3], Op0, Op1); + else if (OpTy->isFPOrFPVector()) + V = ConstantExpr::getVFCmp(Record[3], Op0, Op1); + else + V = ConstantExpr::getVICmp(Record[3], Op0, Op1); break; } case bitc::CST_CODE_INLINEASM: { @@ -809,11 +1001,45 @@ bool BitcodeReader::ParseConstants() { AsmStr, ConstrStr, HasSideEffects); break; } + case bitc::CST_CODE_MDSTRING: { + if (Record.size() < 2) return Error("Invalid MDSTRING record"); + unsigned MDStringLength = Record.size(); + SmallString<8> String; + String.resize(MDStringLength); + for (unsigned i = 0; i != MDStringLength; ++i) + String[i] = Record[i]; + V = MDString::get(String.c_str(), String.c_str() + MDStringLength); + break; + } + case bitc::CST_CODE_MDNODE: { + if (Record.empty() || Record.size() % 2 == 1) + return Error("Invalid CST_MDNODE record"); + + unsigned Size = Record.size(); + SmallVector Elts; + for (unsigned i = 0; i != Size; i += 2) { + const Type *Ty = getTypeByID(Record[i], false); + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], Ty)); + } + V = MDNode::get(&Elts[0], Elts.size()); + break; + } } ValueList.AssignValue(V, NextCstNo); ++NextCstNo; } + + if (NextCstNo != ValueList.size()) + return Error("Invalid constant reference!"); + + if (Stream.ReadBlockEnd()) + return Error("Error at end of constants block"); + + // Once all the constants have been read, go through and resolve forward + // references. + ValueList.ResolveConstantForwardRefs(); + return false; } /// RememberAndSkipFunctionBody - When we see the block for a function body, @@ -854,7 +1080,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { SmallVector Record; std::vector SectionTable; - std::vector CollectorTable; + std::vector GCTable; // Read all the records for this module. while (!Stream.AtEndOfStream()) { @@ -897,7 +1123,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { return Error("Malformed BlockInfoBlock"); break; case bitc::PARAMATTR_BLOCK_ID: - if (ParseParamAttrBlock()) + if (ParseAttributeBlock()) return true; break; case bitc::TYPE_BLOCK_ID: @@ -981,11 +1207,11 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { SectionTable.push_back(S); break; } - case bitc::MODULE_CODE_COLLECTORNAME: { // SECTIONNAME: [strchr x N] + case bitc::MODULE_CODE_GCNAME: { // SECTIONNAME: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) - return Error("Invalid MODULE_CODE_COLLECTORNAME record"); - CollectorTable.push_back(S); + return Error("Invalid MODULE_CODE_GCNAME record"); + GCTable.push_back(S); break; } // GLOBALVAR: [pointer type, isconst, initid, @@ -1032,7 +1258,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { break; } // FUNCTION: [type, callingconv, isproto, linkage, paramattr, - // alignment, section, visibility, collector] + // alignment, section, visibility, gc] case bitc::MODULE_CODE_FUNCTION: { if (Record.size() < 8) return Error("Invalid MODULE_CODE_FUNCTION record"); @@ -1044,14 +1270,13 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { if (!FTy) return Error("Function not a pointer to function type!"); - Function *Func = new Function(FTy, GlobalValue::ExternalLinkage, - "", TheModule); + Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, + "", TheModule); Func->setCallingConv(Record[1]); bool isProto = Record[2]; Func->setLinkage(GetDecodedLinkage(Record[3])); - const ParamAttrsList *PAL = getParamAttrs(Record[4]); - Func->setParamAttrs(PAL); + Func->setAttributes(getAttributes(Record[4])); Func->setAlignment((1 << Record[5]) >> 1); if (Record[6]) { @@ -1061,11 +1286,10 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { } Func->setVisibility(GetDecodedVisibility(Record[7])); if (Record.size() > 8 && Record[8]) { - if (Record[8]-1 > CollectorTable.size()) - return Error("Invalid collector ID"); - Func->setCollector(CollectorTable[Record[8]-1].c_str()); + if (Record[8]-1 > GCTable.size()) + return Error("Invalid GC ID"); + Func->setGC(GCTable[Record[8]-1].c_str()); } - ValueList.push_back(Func); // If this is a function with a body, remember the prototype we are @@ -1075,6 +1299,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { 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"); @@ -1084,6 +1309,9 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { 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; @@ -1102,6 +1330,47 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { return Error("Premature end of bitstream"); } +/// SkipWrapperHeader - Some systems wrap bc files with a special header for +/// padding or other reasons. The format of this header is: +/// +/// 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. +/// ... potentially other gunk ... +/// }; +/// +/// This function is called when we find a file with a matching magic number. +/// In this case, skip down to the subsection of the file that is actually a BC +/// file. +static bool SkipWrapperHeader(unsigned char *&BufPtr, unsigned char *&BufEnd) { + enum { + KnownHeaderSize = 4*4, // Size of header we read. + OffsetField = 2*4, // Offset in bytes to Offset field. + SizeField = 3*4 // Offset in bytes to Size field. + }; + + + // Must contain the header! + if (BufEnd-BufPtr < KnownHeaderSize) return true; + + unsigned Offset = ( BufPtr[OffsetField ] | + (BufPtr[OffsetField+1] << 8) | + (BufPtr[OffsetField+2] << 16) | + (BufPtr[OffsetField+3] << 24)); + unsigned Size = ( BufPtr[SizeField ] | + (BufPtr[SizeField +1] << 8) | + (BufPtr[SizeField +2] << 16) | + (BufPtr[SizeField +3] << 24)); + + // Verify that Offset+Size fits in the file. + if (Offset+Size > unsigned(BufEnd-BufPtr)) + return true; + BufPtr += Offset; + BufEnd = BufPtr+Size; + return false; +} bool BitcodeReader::ParseBitcode() { TheModule = 0; @@ -1110,7 +1379,16 @@ bool BitcodeReader::ParseBitcode() { return Error("Bitcode stream should be a multiple of 4 bytes in length"); unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); - Stream.init(BufPtr, BufPtr+Buffer->getBufferSize()); + unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); + + // 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 (BufPtr != BufEnd && BufPtr[0] == 0xDE && BufPtr[1] == 0xC0 && + BufPtr[2] == 0x17 && BufPtr[3] == 0x0B) + if (SkipWrapperHeader(BufPtr, BufEnd)) + return Error("Invalid bitcode wrapper header"); + + Stream.init(BufPtr, BufEnd); // Sniff for the signature. if (Stream.Read(8) != 'B' || @@ -1211,7 +1489,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // Create all the basic blocks for the function. FunctionBBs.resize(Record[0]); for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i) - FunctionBBs[i] = new BasicBlock("", F); + FunctionBBs[i] = BasicBlock::Create("", F); CurBB = FunctionBBs[0]; continue; @@ -1225,7 +1503,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { int Opc = GetDecodedBinaryOpcode(Record[OpNum], LHS->getType()); if (Opc == -1) return Error("Invalid BINOP record"); - I = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS); + I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); break; } case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc] @@ -1239,7 +1517,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { int Opc = GetDecodedCastOpcode(Record[OpNum+1]); if (Opc == -1 || ResTy == 0) return Error("Invalid CAST record"); - I = CastInst::create((Instruction::CastOps)Opc, Op, ResTy); + I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy); break; } case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands] @@ -1256,11 +1534,58 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { GEPIdx.push_back(Op); } - I = new GetElementPtrInst(BasePtr, GEPIdx.begin(), GEPIdx.end()); + I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end()); + 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 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.begin(), EXTRACTVALIdx.end()); + 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 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.begin(), INSERTVALIdx.end()); 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) || @@ -1268,7 +1593,33 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { getValue(Record, OpNum, Type::Int1Ty, Cond)) return Error("Invalid SELECT record"); - I = new SelectInst(Cond, TrueVal, FalseVal); + I = SelectInst::Create(Cond, TrueVal, FalseVal); + 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) || + getValue(Record, OpNum, TrueVal->getType(), FalseVal) || + getValueTypePair(Record, OpNum, NextValueNo, Cond)) + return Error("Invalid SELECT record"); + + // select condition can be either i1 or [N x i1] + if (const VectorType* vector_type = + dyn_cast(Cond->getType())) { + // expect + if (vector_type->getElementType() != Type::Int1Ty) + return Error("Invalid SELECT condition type"); + } else { + // expect i1 + if (Cond->getType() != Type::Int1Ty) + return Error("Invalid SELECT condition type"); + } + + I = SelectInst::Create(Cond, TrueVal, FalseVal); break; } @@ -1290,7 +1641,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { cast(Vec->getType())->getElementType(), Elt) || getValue(Record, OpNum, Type::Int32Ty, Idx)) return Error("Invalid INSERTELT record"); - I = new InsertElementInst(Vec, Elt, Idx); + I = InsertElementInst::Create(Vec, Elt, Idx); break; } @@ -1301,17 +1652,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { getValue(Record, OpNum, Vec1->getType(), Vec2)) return Error("Invalid SHUFFLEVEC record"); - const Type *MaskTy = - VectorType::get(Type::Int32Ty, - cast(Vec1->getType())->getNumElements()); - - if (getValue(Record, OpNum, MaskTy, Mask)) + if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) return Error("Invalid SHUFFLEVEC record"); I = new ShuffleVectorInst(Vec1, Vec2, Mask); break; } - + case bitc::FUNC_CODE_INST_CMP: { // CMP: [opty, opval, opval, pred] + // VFCmp/VICmp + // or old form of ICmp/FCmp returning bool unsigned OpNum = 0; Value *LHS, *RHS; if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || @@ -1319,9 +1668,28 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { OpNum+1 != Record.size()) return Error("Invalid CMP record"); - if (LHS->getType()->isFPOrFPVector()) + if (LHS->getType()->isFloatingPoint()) I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); + else if (!isa(LHS->getType())) + I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS); + else if (LHS->getType()->isFPOrFPVector()) + I = new VFCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); else + I = new VICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS); + break; + } + 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) || + getValue(Record, OpNum, LHS->getType(), RHS) || + OpNum+1 != Record.size()) + return Error("Invalid CMP2 record"); + + if (LHS->getType()->isFPOrFPVector()) + I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); + else I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS); break; } @@ -1332,7 +1700,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Op; getValueTypePair(Record, OpNum, NextValueNo, Op); unsigned Index = Record[1]; - I = new GetResultInst(Op, Index); + I = ExtractValueInst::Create(Op, Index); break; } @@ -1340,21 +1708,36 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { { unsigned Size = Record.size(); if (Size == 0) { - I = new ReturnInst(); + I = ReturnInst::Create(); break; - } else { - unsigned OpNum = 0; - std::vector Vs; - do { - Value *Op = NULL; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid RET record"); - Vs.push_back(Op); - } while(OpNum != Record.size()); - - I = new ReturnInst(Vs); + } + + unsigned OpNum = 0; + SmallVector Vs; + do { + Value *Op = NULL; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return Error("Invalid RET record"); + Vs.push_back(Op); + } while(OpNum != Record.size()); + + const Type *ReturnType = F->getReturnType(); + if (Vs.size() > 1 || + (isa(ReturnType) && + (Vs.empty() || Vs[0]->getType() != ReturnType))) { + Value *RV = UndefValue::get(ReturnType); + for (unsigned i = 0, e = Vs.size(); i != e; ++i) { + I = InsertValueInst::Create(RV, Vs[i], i, "mrv"); + CurBB->getInstList().push_back(I); + ValueList.AssignValue(I, NextValueNo++); + RV = I; + } + I = ReturnInst::Create(RV); break; } + + I = ReturnInst::Create(Vs[0]); + break; } case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#] if (Record.size() != 1 && Record.size() != 3) @@ -1364,13 +1747,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid BR record"); if (Record.size() == 1) - I = new BranchInst(TrueDest); + I = BranchInst::Create(TrueDest); else { BasicBlock *FalseDest = getBasicBlock(Record[1]); Value *Cond = getFnValueByID(Record[2], Type::Int1Ty); if (FalseDest == 0 || Cond == 0) return Error("Invalid BR record"); - I = new BranchInst(TrueDest, FalseDest, Cond); + I = BranchInst::Create(TrueDest, FalseDest, Cond); } break; } @@ -1383,7 +1766,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (OpTy == 0 || Cond == 0 || Default == 0) return Error("Invalid SWITCH record"); unsigned NumCases = (Record.size()-3)/2; - SwitchInst *SI = new SwitchInst(Cond, Default, NumCases); + SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); for (unsigned i = 0, e = NumCases; i != e; ++i) { ConstantInt *CaseVal = dyn_cast_or_null(getFnValueByID(Record[3+i*2], OpTy)); @@ -1401,7 +1784,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...] if (Record.size() < 4) return Error("Invalid INVOKE record"); - const ParamAttrsList *PAL = getParamAttrs(Record[0]); + AttrListPtr PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; BasicBlock *NormalBB = getBasicBlock(Record[2]); BasicBlock *UnwindBB = getBasicBlock(Record[3]); @@ -1439,9 +1822,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } } - I = new InvokeInst(Callee, NormalBB, UnwindBB, Ops.begin(), Ops.end()); + I = InvokeInst::Create(Callee, NormalBB, UnwindBB, + Ops.begin(), Ops.end()); cast(I)->setCallingConv(CCInfo); - cast(I)->setParamAttrs(PAL); + cast(I)->setAttributes(PAL); break; } case bitc::FUNC_CODE_INST_UNWIND: // UNWIND @@ -1456,8 +1840,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { const Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid PHI record"); - PHINode *PN = new PHINode(Ty); - PN->reserveOperandSpace(Record.size()-1); + PHINode *PN = PHINode::Create(Ty); + PN->reserveOperandSpace((Record.size()-1)/2); for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) { Value *V = getFnValueByID(Record[1+i], Ty); @@ -1539,7 +1923,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid CALL record"); - const ParamAttrsList *PAL = getParamAttrs(Record[0]); + AttrListPtr PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; unsigned OpNum = 2; @@ -1576,10 +1960,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } } - I = new CallInst(Callee, Args.begin(), Args.end()); + I = CallInst::Create(Callee, Args.begin(), Args.end()); cast(I)->setCallingConv(CCInfo>>1); cast(I)->setTailCall(CCInfo & 1); - cast(I)->setParamAttrs(PAL); + cast(I)->setAttributes(PAL); break; } case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty] @@ -1708,7 +2092,8 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) { if (CallInst* CI = dyn_cast(*UI++)) UpgradeIntrinsicCall(CI, I->second); } - ValueList.replaceUsesOfWith(I->first, I->second); + if (!I->first->use_empty()) + I->first->replaceAllUsesWith(I->second); I->first->eraseFromParent(); } }