diff options
Diffstat (limited to 'lib/Bitcode/Reader')
| -rw-r--r-- | lib/Bitcode/Reader/BitReader.cpp | 14 | ||||
| -rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 257 | ||||
| -rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 133 |
3 files changed, 250 insertions, 154 deletions
diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp index 15844c0..5cd6c55 100644 --- a/lib/Bitcode/Reader/BitReader.cpp +++ b/lib/Bitcode/Reader/BitReader.cpp @@ -9,10 +9,10 @@ #include "llvm-c/BitReader.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/MemoryBuffer.h" -#include <string> #include <cstring> +#include <string> using namespace llvm; @@ -30,7 +30,7 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, LLVMModuleRef *OutModule, char **OutMessage) { std::string Message; - + *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef), &Message)); if (!*OutModule) { @@ -38,19 +38,19 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, *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. */ + 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) { @@ -58,7 +58,7 @@ LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, *OutMessage = strdup(Message.c_str()); return 1; } - + return 0; } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index f242df4..59cda22 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -13,19 +13,19 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "BitcodeReader.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Module.h" -#include "llvm/Operator.h" -#include "llvm/AutoUpgrade.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" -#include "llvm/OperandTraits.h" using namespace llvm; enum { @@ -47,11 +47,13 @@ void BitcodeReader::FreeState() { ValueList.clear(); MDValueList.clear(); - std::vector<AttrListPtr>().swap(MAttributes); + 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"); } //===----------------------------------------------------------------------===// @@ -197,7 +199,7 @@ namespace { /// @brief A class for maintaining the slot number definition /// as a placeholder for the actual definition for forward constants defs. class ConstantPlaceHolder : public ConstantExpr { - void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT + void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION; public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -209,7 +211,6 @@ namespace { } /// @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<ConstantExpr>(V) && cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1; @@ -474,18 +475,19 @@ bool BitcodeReader::ParseAttributeBlock() { return Error("Invalid ENTRY record"); for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Attributes ReconstitutedAttr = - Attribute::decodeLLVMAttributesForBitcode(Record[i+1]); - Record[i+1] = ReconstitutedAttr.Raw(); + Attribute ReconstitutedAttr = + Attribute::decodeLLVMAttributesForBitcode(Context, Record[i+1]); + Record[i+1] = ReconstitutedAttr.getBitMask(); } for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - if (Attributes(Record[i+1]) != Attribute::None) + AttrBuilder B(Record[i+1]); + if (B.hasAttributes()) Attrs.push_back(AttributeWithIndex::get(Record[i], - Attributes(Record[i+1]))); + Attribute::get(Context, B))); } - MAttributes.push_back(AttrListPtr::get(Attrs)); + MAttributes.push_back(AttributeSet::get(Context, Attrs)); Attrs.clear(); break; } @@ -605,7 +607,7 @@ bool BitcodeReader::ParseTypeTableBody() { else break; } - + ResultTy = getTypeByID(Record[2]); if (ResultTy == 0 || ArgTys.size() < Record.size()-3) return Error("invalid type in function type"); @@ -624,7 +626,7 @@ bool BitcodeReader::ParseTypeTableBody() { else break; } - + ResultTy = getTypeByID(Record[1]); if (ResultTy == 0 || ArgTys.size() < Record.size()-2) return Error("invalid type in function type"); @@ -655,10 +657,10 @@ bool BitcodeReader::ParseTypeTableBody() { 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) { @@ -667,7 +669,7 @@ bool BitcodeReader::ParseTypeTableBody() { } 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])) @@ -687,7 +689,7 @@ bool BitcodeReader::ParseTypeTableBody() { 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) { @@ -698,7 +700,7 @@ bool BitcodeReader::ParseTypeTableBody() { TypeName.clear(); ResultTy = Res; break; - } + } case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] if (Record.size() < 2) return Error("Invalid ARRAY type record"); @@ -889,9 +891,9 @@ bool BitcodeReader::ParseMetadata() { } } -/// DecodeSignRotatedValue - Decode a signed value stored with the sign bit in +/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in /// the LSB for dense VBR encoding. -static uint64_t DecodeSignRotatedValue(uint64_t V) { +uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { if ((V & 1) == 0) return V >> 1; if (V != 1) @@ -941,7 +943,7 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { SmallVector<uint64_t, 8> Words(Vals.size()); std::transform(Vals.begin(), Vals.end(), Words.begin(), - DecodeSignRotatedValue); + BitcodeReader::decodeSignRotatedValue); return APInt(TypeBits, Words); } @@ -995,7 +997,7 @@ bool BitcodeReader::ParseConstants() { 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])); + V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); break; case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] if (!CurTy->isIntegerTy() || Record.empty()) @@ -1004,7 +1006,7 @@ bool BitcodeReader::ParseConstants() { APInt VInt = ReadWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); V = ConstantInt::get(Context, VInt); - + break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] @@ -1071,10 +1073,10 @@ bool BitcodeReader::ParseConstants() { 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)) @@ -1180,10 +1182,11 @@ bool BitcodeReader::ParseConstants() { } 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)); + 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"); @@ -1191,7 +1194,8 @@ bool BitcodeReader::ParseConstants() { 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)); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], + Type::getInt32Ty(Context)); V = ConstantExpr::getExtractElement(Op0, Op1); break; } @@ -1202,7 +1206,8 @@ bool BitcodeReader::ParseConstants() { Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy->getElementType()); - Constant *Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + Constant *Op2 = ValueList.getConstantFwdRef(Record[2], + Type::getInt32Ty(Context)); V = ConstantExpr::getInsertElement(Op0, Op1, Op2); break; } @@ -1300,15 +1305,29 @@ bool BitcodeReader::ParseConstants() { Function *Fn = dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy)); if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record"); - - GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(), - Type::getInt8Ty(Context), + + // 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; + 0, ""); + BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef)); + V = FwdRef; + } break; - } + } } ValueList.AssignValue(V, NextCstNo); @@ -1332,7 +1351,7 @@ bool BitcodeReader::ParseUseLists() { return Error("Malformed block record"); SmallVector<uint64_t, 64> Record; - + // Read all the records. while (1) { unsigned Code = Stream.ReadCode(); @@ -1341,7 +1360,7 @@ bool BitcodeReader::ParseUseLists() { return Error("Error at end of use-list table block"); return false; } - + if (Code == bitc::ENTER_SUBBLOCK) { // No known subblocks, always skip them. Stream.ReadSubBlockID(); @@ -1349,12 +1368,12 @@ bool BitcodeReader::ParseUseLists() { return Error("Malformed block record"); continue; } - + if (Code == bitc::DEFINE_ABBREV) { Stream.ReadAbbrevRecord(); continue; } - + // Read a use list record. Record.clear(); switch (Stream.ReadRecord(Code, Record)) { @@ -1508,13 +1527,22 @@ bool BitcodeReader::ParseModule(bool Resume) { // Read a record. switch (Stream.ReadRecord(Code, Record)) { default: break; // Default behavior, ignore unknown content. - case bitc::MODULE_CODE_VERSION: // VERSION: [version#] + case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] if (Record.size() < 1) return Error("Malformed MODULE_CODE_VERSION"); - // Only version #0 is supported so far. - if (Record[0] != 0) - return Error("Unknown bitstream 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)) @@ -1537,10 +1565,11 @@ bool BitcodeReader::ParseModule(bool Resume) { 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"); - TheModule->addLibrary(S); + // Ignore value. break; } case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] @@ -1781,13 +1810,6 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { // Read a record. switch (Stream.ReadRecord(Code, 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 is supported so far. - if (Record[0] != 0) - return Error("Unknown bitstream version!"); - break; case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; if (ConvertToString(Record, 0, S)) @@ -1901,7 +1923,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned CurBBNo = 0; DebugLoc LastLoc; - + // Read all the records. SmallVector<uint64_t, 64> Record; while (1) { @@ -1956,24 +1978,24 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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()) @@ -1983,10 +2005,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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)); @@ -2000,7 +2022,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *LHS, *RHS; if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || - getValue(Record, OpNum, LHS->getType(), RHS) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || OpNum+1 > Record.size()) return Error("Invalid BINOP record"); @@ -2023,7 +2045,22 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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; } @@ -2115,8 +2152,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || - getValue(Record, OpNum, TrueVal->getType(), FalseVal) || - getValue(Record, OpNum, Type::getInt1Ty(Context), Cond)) + 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); @@ -2130,7 +2167,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *TrueVal, *FalseVal, *Cond; if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || - getValue(Record, OpNum, TrueVal->getType(), FalseVal) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || getValueTypePair(Record, OpNum, NextValueNo, Cond)) return Error("Invalid SELECT record"); @@ -2155,7 +2192,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Vec, *Idx; if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || - getValue(Record, OpNum, Type::getInt32Ty(Context), Idx)) + popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx)) return Error("Invalid EXTRACTELT record"); I = ExtractElementInst::Create(Vec, Idx); InstructionList.push_back(I); @@ -2166,9 +2203,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Vec, *Elt, *Idx; if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<VectorType>(Vec->getType())->getElementType(), Elt) || - getValue(Record, OpNum, Type::getInt32Ty(Context), Idx)) + popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx)) return Error("Invalid INSERTELT record"); I = InsertElementInst::Create(Vec, Elt, Idx); InstructionList.push_back(I); @@ -2179,7 +2216,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Vec1, *Vec2, *Mask; if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || - getValue(Record, OpNum, Vec1->getType(), Vec2)) + popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) return Error("Invalid SHUFFLEVEC record"); if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) @@ -2199,7 +2236,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *LHS, *RHS; if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || - getValue(Record, OpNum, LHS->getType(), RHS) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || OpNum+1 != Record.size()) return Error("Invalid CMP record"); @@ -2244,7 +2281,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { } else { BasicBlock *FalseDest = getBasicBlock(Record[1]); - Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context)); + 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); @@ -2253,30 +2291,30 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] - // Check magic + // 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 = getFnValueByID(Record[2], OpTy); + 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) @@ -2292,7 +2330,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { APInt High = ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords), ValueBitWidth); - + CaseBuilder.add(IntItem::fromType(OpTy, Low), IntItem::fromType(OpTy, High)); CurIdx += ActiveWords; @@ -2300,7 +2338,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { CaseBuilder.add(IntItem::fromType(OpTy, Low)); } BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]); - IntegersSubset Case = CaseBuilder.getCase(); + IntegersSubset Case = CaseBuilder.getCase(); SI->addCase(Case, DestBB); } uint16_t Hash = SI->hash(); @@ -2309,13 +2347,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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 = getFnValueByID(Record[1], OpTy); + Value *Cond = getValue(Record, 1, NextValueNo, OpTy); BasicBlock *Default = getBasicBlock(Record[2]); if (OpTy == 0 || Cond == 0 || Default == 0) return Error("Invalid SWITCH record"); @@ -2339,7 +2377,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 2) return Error("Invalid INDIRECTBR record"); Type *OpTy = getTypeByID(Record[0]); - Value *Address = getFnValueByID(Record[1], OpTy); + Value *Address = getValue(Record, 1, NextValueNo, OpTy); if (OpTy == 0 || Address == 0) return Error("Invalid INDIRECTBR record"); unsigned NumDests = Record.size()-2; @@ -2356,11 +2394,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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"); - AttrListPtr PAL = getAttributes(Record[0]); + AttributeSet PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; BasicBlock *NormalBB = getBasicBlock(Record[2]); BasicBlock *UnwindBB = getBasicBlock(Record[3]); @@ -2381,7 +2419,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { SmallVector<Value*, 16> Ops; for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { - Ops.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i))); + Ops.push_back(getValue(Record, OpNum, NextValueNo, + FTy->getParamType(i))); if (Ops.back() == 0) return Error("Invalid INVOKE record"); } @@ -2428,7 +2467,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(PN); for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) { - Value *V = getFnValueByID(Record[1+i], Ty); + 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); @@ -2507,7 +2553,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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 || @@ -2526,7 +2572,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+2 != Record.size()) return Error("Invalid STORE record"); @@ -2540,7 +2586,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+4 != Record.size()) return Error("Invalid STOREATOMIC record"); @@ -2563,9 +2609,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Ptr, *Cmp, *New; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Cmp) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), New) || OpNum+3 != Record.size()) return Error("Invalid CMPXCHG record"); @@ -2583,7 +2629,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Ptr, *Val; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - getValue(Record, OpNum, + popValue(Record, OpNum, NextValueNo, cast<PointerType>(Ptr->getType())->getElementType(), Val) || OpNum+4 != Record.size()) return Error("Invalid ATOMICRMW record"); @@ -2617,7 +2663,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid CALL record"); - AttrListPtr PAL = getAttributes(Record[0]); + AttributeSet PAL = getAttributes(Record[0]); unsigned CCInfo = Record[1]; unsigned OpNum = 2; @@ -2637,7 +2683,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (FTy->getParamType(i)->isLabelTy()) Args.push_back(getBasicBlock(Record[OpNum])); else - Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i))); + Args.push_back(getValue(Record, OpNum, NextValueNo, + FTy->getParamType(i))); if (Args.back() == 0) return Error("Invalid CALL record"); } @@ -2666,7 +2713,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid VAARG record"); Type *OpTy = getTypeByID(Record[0]); - Value *Op = getFnValueByID(Record[1], OpTy); + Value *Op = getValue(Record, 1, NextValueNo, OpTy); Type *ResTy = getTypeByID(Record[2]); if (!OpTy || !Op || !ResTy) return Error("Invalid VAARG record"); @@ -2722,15 +2769,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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); diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index e7c4e94..3347418 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -14,27 +14,27 @@ #ifndef BITCODE_READER_H #define BITCODE_READER_H -#include "llvm/GVMaterializer.h" -#include "llvm/Attributes.h" -#include "llvm/Type.h" -#include "llvm/OperandTraits.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 "llvm/ADT/DenseMap.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 @@ -57,17 +57,17 @@ public: 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(); } @@ -75,12 +75,12 @@ public: 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(); @@ -93,7 +93,7 @@ public: class BitcodeReaderMDValueList { std::vector<WeakVH> MDValuePtrs; - + LLVMContext &Context; public: BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {} @@ -106,12 +106,12 @@ public: 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); @@ -131,9 +131,9 @@ class BitcodeReader : public GVMaterializer { DataStreamer *LazyStreamer; uint64_t NextUnreadBit; bool SeenValueSymbolTable; - + const char *ErrorString; - + std::vector<Type*> TypeList; BitcodeReaderValueList ValueList; BitcodeReaderMDValueList MDValueList; @@ -142,55 +142,64 @@ class BitcodeReader : public GVMaterializer { 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<AttrListPtr> MAttributes; - + std::vector<AttributeSet> MAttributes; + /// 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 + // 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) { + 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) { + SeenFirstFunctionBody(false), UseRelativeIDs(false) { } ~BitcodeReader() { FreeState(); @@ -199,11 +208,11 @@ public: 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); @@ -215,7 +224,7 @@ public: 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); @@ -223,6 +232,9 @@ public: /// @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) { @@ -234,12 +246,12 @@ private: if (ID >= FunctionBBs.size()) return 0; // Invalid ID return FunctionBBs[ID]; } - AttrListPtr getAttributes(unsigned i) const { + AttributeSet getAttributes(unsigned i) const { if (i-1 < MAttributes.size()) return MAttributes[i-1]; - return AttrListPtr(); + 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. @@ -247,6 +259,9 @@ private: 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. @@ -255,20 +270,54 @@ private: } else if (Slot == Record.size()) { return true; } - + unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); return ResVal == 0; } - bool getValue(SmallVector<uint64_t, 64> &Record, unsigned &Slot, - Type *Ty, Value *&ResVal) { - if (Slot == Record.size()) return true; - unsigned ValNo = (unsigned)Record[Slot++]; - ResVal = getFnValueByID(ValNo, Ty); + + /// 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 ParseTypeTable(); @@ -290,7 +339,7 @@ private: bool FindFunctionInStream(Function *F, DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator); }; - + } // End llvm namespace #endif |
