X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.cpp;h=2d994d4b13d03d71bab25d111a0d0e2bfacec3b5;hb=73ddd4f00dd2a4b7b68a1500bc7e3322cab51270;hp=3fc6b17521710f35aa20a458a214681ac00cff9f;hpb=0aab28bf4c3ec21c2a068733373e37c68c376171;p=oota-llvm.git diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 3fc6b175217..2d994d4b13d 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -32,7 +32,7 @@ void BitcodeReader::FreeState() { std::vector().swap(TypeList); ValueList.clear(); - std::vector().swap(ParamAttrs); + std::vector().swap(MAttributes); std::vector().swap(FunctionBBs); std::vector().swap(FunctionsWithBodies); DeferredFunctionInfo.clear(); @@ -133,6 +133,15 @@ namespace { : 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); }; @@ -205,6 +214,87 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { return V; } +/// ResolveConstantForwardRefs - Once all constants are read, this method bulk +/// resolves any forward references. The idea behind this is that we sometimes +/// get constants (such as large arrays) which reference *many* forward ref +/// constants. Replacing each of these causes a lot of thrashing when +/// building/reuniquing the constant. Instead of doing this, we look at all the +/// uses and rewrite all the place holders at once for any constant that uses +/// a placeholder. +void BitcodeReaderValueList::ResolveConstantForwardRefs() { + // 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 = getOperand(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 = this->getOperand(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 { + // Must be a constant expression. + NewC = cast(UserC)->getWithOperands(&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. @@ -223,16 +313,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; - SmallVector Attrs; + SmallVector Attrs; // Read all the records. while (1) { @@ -265,12 +355,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(PAListPtr::get(Attrs.begin(), Attrs.end())); + 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; } @@ -602,14 +739,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. @@ -770,47 +901,6 @@ bool BitcodeReader::ParseConstants() { V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1); break; } - case bitc::CST_CODE_CE_EXTRACTVAL: { - // CE_EXTRACTVAL: [opty, opval, n x indices] - const Type *AggTy = getTypeByID(Record[0]); - if (!AggTy || !AggTy->isAggregateType()) - return Error("Invalid CE_EXTRACTVAL record"); - Constant *Agg = ValueList.getConstantFwdRef(Record[1], AggTy); - SmallVector Indices; - for (unsigned i = 2, e = Record.size(); i != e; ++i) { - uint64_t Index = Record[i]; - if ((unsigned)Index != Index) - return Error("Invalid CE_EXTRACTVAL record"); - Indices.push_back((unsigned)Index); - } - if (!ExtractValueInst::getIndexedType(AggTy, - Indices.begin(), Indices.end())) - return Error("Invalid CE_EXTRACTVAL record"); - V = ConstantExpr::getExtractValue(Agg, &Indices[0], Indices.size()); - break; - } - case bitc::CST_CODE_CE_INSERTVAL: { - // CE_INSERTVAL: [opty, opval, opty, opval, n x indices] - const Type *AggTy = getTypeByID(Record[0]); - if (!AggTy || !AggTy->isAggregateType()) - return Error("Invalid CE_INSERTVAL record"); - Constant *Agg = ValueList.getConstantFwdRef(Record[1], AggTy); - const Type *ValTy = getTypeByID(Record[2]); - Constant *Val = ValueList.getConstantFwdRef(Record[3], ValTy); - SmallVector Indices; - for (unsigned i = 4, e = Record.size(); i != e; ++i) { - uint64_t Index = Record[i]; - if ((unsigned)Index != Index) - return Error("Invalid CE_INSERTVAL record"); - Indices.push_back((unsigned)Index); - } - if (ExtractValueInst::getIndexedType(AggTy, - Indices.begin(), - Indices.end()) != ValTy) - return Error("Invalid CE_INSERTVAL record"); - V = ConstantExpr::getInsertValue(Agg, Val, &Indices[0], Indices.size()); - 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], @@ -893,6 +983,17 @@ bool BitcodeReader::ParseConstants() { 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, @@ -933,7 +1034,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()) { @@ -976,7 +1077,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: @@ -1060,11 +1161,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, @@ -1111,7 +1212,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"); @@ -1129,7 +1230,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { Func->setCallingConv(Record[1]); bool isProto = Record[2]; Func->setLinkage(GetDecodedLinkage(Record[3])); - Func->setParamAttrs(getParamAttrs(Record[4])); + Func->setAttributes(getAttributes(Record[4])); Func->setAlignment((1 << Record[5]) >> 1); if (Record[6]) { @@ -1139,11 +1240,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 @@ -1184,6 +1284,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; @@ -1192,7 +1333,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' || @@ -1388,6 +1538,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } 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) || @@ -1399,6 +1551,32 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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; + } + case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval] unsigned OpNum = 0; Value *Vec, *Idx; @@ -1428,17 +1606,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) || @@ -1456,6 +1632,21 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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; + } case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n] if (Record.size() != 2) return Error("Invalid GETRESULT record"); @@ -1463,7 +1654,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; } @@ -1473,20 +1664,34 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Size == 0) { I = ReturnInst::Create(); break; - } else { - 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()); - - // SmallVector Vs has at least one element. - I = ReturnInst::Create(&Vs[0], Vs.size()); + } + + 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) @@ -1533,7 +1738,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"); - PAListPtr PAL = getParamAttrs(Record[0]); + AttrListPtr PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; BasicBlock *NormalBB = getBasicBlock(Record[2]); BasicBlock *UnwindBB = getBasicBlock(Record[3]); @@ -1574,7 +1779,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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 @@ -1672,7 +1877,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid CALL record"); - PAListPtr PAL = getParamAttrs(Record[0]); + AttrListPtr PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; unsigned OpNum = 2; @@ -1712,7 +1917,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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]