diff options
Diffstat (limited to 'lib/Bitcode/Reader')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 206 | ||||
-rw-r--r-- | lib/Bitcode/Reader/CMakeLists.txt | 2 |
2 files changed, 112 insertions, 96 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e399040..4ffee38 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -28,6 +28,10 @@ #include "llvm/OperandTraits.h" using namespace llvm; +enum { + SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex +}; + void BitcodeReader::materializeForwardReferencedFunctions() { while (!BlockAddrFwdRefs.empty()) { Function *F = BlockAddrFwdRefs.begin()->first; @@ -57,7 +61,7 @@ void BitcodeReader::FreeState() { /// ConvertToString - Convert a string from a record into an std::string, return /// true on failure. template<typename StrTy> -static bool ConvertToString(SmallVector<uint64_t, 64> &Record, unsigned Idx, +static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx, StrTy &Result) { if (Idx > Record.size()) return true; @@ -98,6 +102,17 @@ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) { } } +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; @@ -458,61 +473,19 @@ bool BitcodeReader::ParseAttributeBlock() { 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; - Attributes FnAttribute; for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - // 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 |= - Attributes((Record[i+1] & (0xffffull << 32)) >> 11); - + Attributes ReconstitutedAttr = + Attribute::decodeLLVMAttributesForBitcode(Record[i+1]); Record[i+1] = ReconstitutedAttr.Raw(); - if (Record[i] == 0) - RetAttribute = ReconstitutedAttr; - else if (Record[i] == ~0U) - FnAttribute = ReconstitutedAttr; - } - - Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn| - Attribute::ReadOnly|Attribute::ReadNone); - - if (FnAttribute == Attribute::None && RetAttribute != Attribute::None && - (RetAttribute & OldRetAttrs)) { - 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 (Attributes(Record[i+1]) != Attribute::None) + if (Attributes(Record[i+1]) != Attribute::None) Attrs.push_back(AttributeWithIndex::get(Record[i], Attributes(Record[i+1]))); } - MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end())); + MAttributes.push_back(AttrListPtr::get(Attrs)); Attrs.clear(); break; } @@ -621,7 +594,7 @@ bool BitcodeReader::ParseTypeTableBody() { break; } case bitc::TYPE_CODE_FUNCTION_OLD: { - // FIXME: attrid is dead, remove it in LLVM 3.0 + // 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"); @@ -851,11 +824,7 @@ bool BitcodeReader::ParseMetadata() { break; case bitc::METADATA_NAME: { // Read named of the named metadata. - unsigned NameLength = Record.size(); - SmallString<8> Name; - Name.resize(NameLength); - for (unsigned i = 0; i != NameLength; ++i) - Name[i] = Record[i]; + SmallString<8> Name(Record.begin(), Record.end()); Record.clear(); Code = Stream.ReadCode(); @@ -899,26 +868,18 @@ bool BitcodeReader::ParseMetadata() { break; } case bitc::METADATA_STRING: { - unsigned MDStringLength = Record.size(); - SmallString<8> String; - String.resize(MDStringLength); - for (unsigned i = 0; i != MDStringLength; ++i) - String[i] = Record[i]; - Value *V = MDString::get(Context, - StringRef(String.data(), String.size())); + SmallString<8> String(Record.begin(), Record.end()); + Value *V = MDString::get(Context, String); MDValueList.AssignValue(V, NextMDValueNo++); break; } case bitc::METADATA_KIND: { - unsigned RecordLength = Record.size(); - if (Record.empty() || RecordLength < 2) + if (Record.size() < 2) return Error("Invalid METADATA_KIND record"); - SmallString<8> Name; - Name.resize(RecordLength-1); + unsigned Kind = Record[0]; - for (unsigned i = 1; i != RecordLength; ++i) - Name[i-1] = Record[i]; - + 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"); @@ -977,6 +938,14 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() { 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(), + DecodeSignRotatedValue); + + return APInt(TypeBits, Words); +} + bool BitcodeReader::ParseConstants() { if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) return Error("Malformed block record"); @@ -1032,14 +1001,10 @@ bool BitcodeReader::ParseConstants() { if (!CurTy->isIntegerTy() || Record.empty()) return Error("Invalid WIDE_INTEGER record"); - unsigned NumWords = Record.size(); - SmallVector<uint64_t, 8> Words; - Words.resize(NumWords); - for (unsigned i = 0; i != NumWords; ++i) - Words[i] = DecodeSignRotatedValue(Record[i]); - V = ConstantInt::get(Context, - APInt(cast<IntegerType>(CurTy)->getBitWidth(), - Words)); + APInt VInt = ReadWideAPInt(Record, + cast<IntegerType>(CurTy)->getBitWidth()); + V = ConstantInt::get(Context, VInt); + break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] @@ -1098,10 +1063,7 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid CST_STRING record"); - unsigned Size = Record.size(); - SmallString<16> Elts; - for (unsigned i = 0; i != Size; ++i) - Elts.push_back(Record[i]); + SmallString<16> Elts(Record.begin(), Record.end()); V = ConstantDataArray::getString(Context, Elts, BitCode == bitc::CST_CODE_CSTRING); break; @@ -1138,23 +1100,16 @@ bool BitcodeReader::ParseConstants() { else V = ConstantDataArray::get(Context, Elts); } else if (EltTy->isFloatTy()) { - SmallVector<float, 16> Elts; - for (unsigned i = 0; i != Size; ++i) { - union { uint32_t I; float F; }; - I = Record[i]; - Elts.push_back(F); - } + 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; - for (unsigned i = 0; i != Size; ++i) { - union { uint64_t I; double F; }; - I = Record[i]; - Elts.push_back(F); - } + SmallVector<double, 16> Elts(Size); + std::transform(Record.begin(), Record.end(), Elts.begin(), + BitsToDouble); if (isa<VectorType>(CurTy)) V = ConstantDataVector::get(Context, Elts); else @@ -1600,9 +1555,10 @@ bool BitcodeReader::ParseModule(bool Resume) { GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; if (Record.size() > 6) Visibility = GetDecodedVisibility(Record[6]); - bool isThreadLocal = false; + + GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal; if (Record.size() > 7) - isThreadLocal = Record[7]; + TLM = GetDecodedThreadLocalMode(Record[7]); bool UnnamedAddr = false; if (Record.size() > 8) @@ -1610,12 +1566,11 @@ bool BitcodeReader::ParseModule(bool Resume) { GlobalVariable *NewGV = new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0, - isThreadLocal, AddressSpace); + TLM, AddressSpace); NewGV->setAlignment(Alignment); if (!Section.empty()) NewGV->setSection(Section); NewGV->setVisibility(Visibility); - NewGV->setThreadLocal(isThreadLocal); NewGV->setUnnamedAddr(UnnamedAddr); ValueList.push_back(NewGV); @@ -1732,7 +1687,7 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { // have to read and ignore these final 4 bytes :-( if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && - Stream.AtEndOfStream()) + Stream.AtEndOfStream()) return false; return Error("Invalid record at top-level"); @@ -2271,6 +2226,65 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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 = getFnValueByID(Record[2], 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]); diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt index 693d431..dfe7e10 100644 --- a/lib/Bitcode/Reader/CMakeLists.txt +++ b/lib/Bitcode/Reader/CMakeLists.txt @@ -2,3 +2,5 @@ add_llvm_library(LLVMBitReader BitReader.cpp BitcodeReader.cpp ) + +add_dependencies(LLVMBitReader intrinsics_gen) |