diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/Reader/BitReader.cpp | 14 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 686 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 70 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitstreamReader.cpp | 371 | ||||
-rw-r--r-- | lib/Bitcode/Reader/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitWriter.cpp | 9 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 210 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriterPass.cpp | 4 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 64 | ||||
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.h | 52 |
10 files changed, 1013 insertions, 468 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 4ec9da1..f348843 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6,26 +6,22 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This header defines the BitcodeReader class. -// -//===----------------------------------------------------------------------===// #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,7 +43,7 @@ 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(); @@ -432,6 +428,26 @@ Type *BitcodeReader::getTypeByID(unsigned ID) { // Functions for parsing blocks from the bitcode file //===----------------------------------------------------------------------===// + +/// \brief This fills an AttrBuilder object with the LLVM attributes that have +/// been decoded from the given integer. This function must stay in sync with +/// 'encodeLLVMAttributesForBitcode'. +static void decodeLLVMAttributesForBitcode(AttrBuilder &B, + uint64_t EncodedAttrs) { + // FIXME: Remove in 4.0. + + // The alignment is stored as a 16-bit raw value from bits 31--16. We shift + // the bits above 31 down by 11 bits. + unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; + assert((!Alignment || isPowerOf2_32(Alignment)) && + "Alignment must be a power of two."); + + if (Alignment) + B.addAlignmentAttr(Alignment); + B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff)); +} + bool BitcodeReader::ParseAttributeBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) return Error("Malformed block record"); @@ -441,54 +457,124 @@ bool BitcodeReader::ParseAttributeBlock() { SmallVector<uint64_t, 64> Record; - SmallVector<AttributeWithIndex, 8> Attrs; + SmallVector<AttributeSet, 8> Attrs; // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("Error at end of PARAMATTR block"); + case BitstreamEntry::EndBlock: return false; + case BitstreamEntry::Record: + // The interesting case. + break; } - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; + // Read a record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: ignore. + break; + case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...] + // FIXME: Remove in 4.0. + if (Record.size() & 1) + return Error("Invalid ENTRY record"); + + for (unsigned i = 0, e = Record.size(); i != e; i += 2) { + AttrBuilder B; + decodeLLVMAttributesForBitcode(B, Record[i+1]); + Attrs.push_back(AttributeSet::get(Context, Record[i], B)); + } + + MAttributes.push_back(AttributeSet::get(Context, Attrs)); + Attrs.clear(); + break; } + case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...] + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Attrs.push_back(MAttributeGroups[Record[i]]); - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + MAttributes.push_back(AttributeSet::get(Context, Attrs)); + Attrs.clear(); + break; + } + } + } +} + +bool BitcodeReader::ParseAttributeGroupBlock() { + if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) + return Error("Malformed block record"); + + if (!MAttributeGroups.empty()) + return Error("Multiple PARAMATTR_GROUP blocks found!"); + + SmallVector<uint64_t, 64> Record; + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("Error at end of PARAMATTR_GROUP block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: ignore. break; - case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...] - if (Record.size() & 1) + case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] + if (Record.size() < 3) return Error("Invalid ENTRY record"); - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Attributes ReconstitutedAttr = - Attributes::decodeLLVMAttributesForBitcode(Context, Record[i+1]); - Record[i+1] = ReconstitutedAttr.Raw(); - } + uint64_t GrpID = Record[0]; + uint64_t Idx = Record[1]; // Index of the object this attribute refers to. - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - AttrBuilder B(Record[i+1]); - if (B.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(Record[i], - Attributes::get(Context, B))); + AttrBuilder B; + for (unsigned i = 2, e = Record.size(); i != e; ++i) { + if (Record[i] == 0) { // Enum attribute + B.addAttribute(Attribute::AttrKind(Record[++i])); + } else if (Record[i] == 1) { // Align attribute + if (Attribute::AttrKind(Record[++i]) == Attribute::Alignment) + B.addAlignmentAttr(Record[++i]); + else + B.addStackAlignmentAttr(Record[++i]); + } else { // String attribute + assert((Record[i] == 3 || Record[i] == 4) && + "Invalid attribute group entry"); + bool HasValue = (Record[i++] == 4); + SmallString<64> KindStr; + SmallString<64> ValStr; + + while (Record[i] != 0 && i != e) + KindStr += Record[i++]; + assert(Record[i] == 0 && "Kind string not null terminated"); + + if (HasValue) { + // Has a value associated with it. + ++i; // Skip the '0' that terminates the "kind" string. + while (Record[i] != 0 && i != e) + ValStr += Record[i++]; + assert(Record[i] == 0 && "Value string not null terminated"); + } + + B.addAttribute(KindStr.str(), ValStr.str()); + } } - MAttributes.push_back(AttrListPtr::get(Context, Attrs)); - Attrs.clear(); + MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); break; } } @@ -513,32 +599,26 @@ bool BitcodeReader::ParseTypeTableBody() { // Read all the records for this type table. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + Error("Error in the type table block"); + return true; + case BitstreamEntry::EndBlock: if (NumRecords != TypeList.size()) return Error("Invalid type forward reference in TYPE_BLOCK"); - if (Stream.ReadBlockEnd()) - return Error("Error at end of type table block"); return false; - } - - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } - - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); Type *ResultTy = 0; - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: return Error("unknown type in type table"); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] // TYPE_CODE_NUMENTRY contains a count of the number of types in the @@ -607,7 +687,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"); @@ -626,7 +706,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"); @@ -657,10 +737,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) { @@ -669,7 +749,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])) @@ -689,7 +769,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) { @@ -700,7 +780,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"); @@ -736,28 +816,22 @@ bool BitcodeReader::ParseValueSymbolTable() { // Read all the records for this value table. SmallString<128> ValueName; while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of value symbol table block"); - return false; - } - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed value symbol table block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: unknown type. break; case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] @@ -797,41 +871,35 @@ bool BitcodeReader::ParseMetadata() { // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); - return false; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } - - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + Error("malformed metadata block"); + return true; + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } bool IsFunctionLocal = false; // Read a record. Record.clear(); - Code = Stream.ReadRecord(Code, Record); + unsigned Code = Stream.readRecord(Entry.ID, Record); switch (Code) { default: // Default behavior: ignore. break; case bitc::METADATA_NAME: { - // Read named of the named metadata. + // Read name of the named metadata. SmallString<8> Name(Record.begin(), Record.end()); Record.clear(); Code = Stream.ReadCode(); // METADATA_NAME is always followed by METADATA_NAMED_NODE. - unsigned NextBitCode = Stream.ReadRecord(Code, Record); + unsigned NextBitCode = Stream.readRecord(Code, Record); assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode; // Read named metadata elements. @@ -958,27 +1026,29 @@ bool BitcodeReader::ParseConstants() { Type *CurTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed block record in AST file"); + case BitstreamEntry::EndBlock: + if (NextCstNo != ValueList.size()) + return Error("Invalid constant reference!"); + + // Once all the constants have been read, go through and resolve forward + // references. + ValueList.ResolveConstantForwardRefs(); + return false; + case BitstreamEntry::Record: + // The interesting case. break; - - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } - - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; } // Read a record. Record.clear(); Value *V = 0; - unsigned BitCode = Stream.ReadRecord(Code, Record); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); switch (BitCode) { default: // Default behavior: unknown constant case bitc::CST_CODE_UNDEF: // UNDEF @@ -1006,28 +1076,34 @@ bool BitcodeReader::ParseConstants() { APInt VInt = ReadWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); V = ConstantInt::get(Context, VInt); - + break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] if (Record.empty()) return Error("Invalid FLOAT record"); if (CurTy->isHalfTy()) - V = ConstantFP::get(Context, APFloat(APInt(16, (uint16_t)Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf, + APInt(16, (uint16_t)Record[0]))); else if (CurTy->isFloatTy()) - V = ConstantFP::get(Context, APFloat(APInt(32, (uint32_t)Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle, + APInt(32, (uint32_t)Record[0]))); else if (CurTy->isDoubleTy()) - V = ConstantFP::get(Context, APFloat(APInt(64, Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble, + APInt(64, Record[0]))); else if (CurTy->isX86_FP80Ty()) { // Bits are not stored the same way as a normal i80 APInt, compensate. uint64_t Rearrange[2]; Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[1] = Record[0] >> 48; - V = ConstantFP::get(Context, APFloat(APInt(80, Rearrange))); + V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended, + APInt(80, Rearrange))); } else if (CurTy->isFP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, Record), true)); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad, + APInt(128, Record))); else if (CurTy->isPPC_FP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, Record))); + V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble, + APInt(128, Record))); else V = UndefValue::get(CurTy); break; @@ -1073,10 +1149,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)) @@ -1182,10 +1258,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"); @@ -1193,7 +1270,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; } @@ -1204,7 +1282,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; } @@ -1324,23 +1403,12 @@ bool BitcodeReader::ParseConstants() { V = FwdRef; } 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; } bool BitcodeReader::ParseUseLists() { @@ -1348,32 +1416,25 @@ bool BitcodeReader::ParseUseLists() { return Error("Malformed block record"); SmallVector<uint64_t, 64> Record; - + // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of use-list table block"); + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed use list block"); + case BitstreamEntry::EndBlock: return false; + case BitstreamEntry::Record: + // The interesting case. + break; } - - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - 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)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: unknown type. break; case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD. @@ -1445,17 +1506,18 @@ bool BitcodeReader::ParseModule(bool Resume) { std::vector<std::string> GCTable; // Read all the records for this module. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of module block"); + while (1) { + BitstreamEntry Entry = Stream.advance(); + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module block"); + return true; + case BitstreamEntry::EndBlock: return GlobalCleanup(); - } - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { + case BitstreamEntry::SubBlock: + switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) return Error("Malformed block record"); @@ -1468,6 +1530,10 @@ bool BitcodeReader::ParseModule(bool Resume) { if (ParseAttributeBlock()) return true; break; + case bitc::PARAMATTR_GROUP_BLOCK_ID: + if (ParseAttributeGroupBlock()) + return true; + break; case bitc::TYPE_BLOCK_ID_NEW: if (ParseTypeTable()) return true; @@ -1514,15 +1580,15 @@ bool BitcodeReader::ParseModule(bool Resume) { break; } continue; - } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } + // Read a record. - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] if (Record.size() < 1) @@ -1562,10 +1628,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] @@ -1616,9 +1683,13 @@ bool BitcodeReader::ParseModule(bool Resume) { if (Record.size() > 8) UnnamedAddr = Record[8]; + bool ExternallyInitialized = false; + if (Record.size() > 9) + ExternallyInitialized = Record[9]; + GlobalVariable *NewGV = new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0, - TLM, AddressSpace); + TLM, AddressSpace, ExternallyInitialized); NewGV->setAlignment(Alignment); if (!Section.empty()) NewGV->setSection(Section); @@ -1709,8 +1780,6 @@ bool BitcodeReader::ParseModule(bool Resume) { } Record.clear(); } - - return Error("Premature end of bitstream"); } bool BitcodeReader::ParseBitcodeInto(Module *M) { @@ -1729,47 +1798,55 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); + while (1) { + if (Stream.AtEndOfStream()) + return false; + + BitstreamEntry Entry = + Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); - if (Code != bitc::ENTER_SUBBLOCK) { + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module file"); + return true; + case BitstreamEntry::EndBlock: + return false; + + case BitstreamEntry::SubBlock: + switch (Entry.ID) { + case bitc::BLOCKINFO_BLOCK_ID: + if (Stream.ReadBlockInfoBlock()) + return Error("Malformed BlockInfoBlock"); + break; + case bitc::MODULE_BLOCK_ID: + // Reject multiple MODULE_BLOCK's in a single bitstream. + if (TheModule) + return Error("Multiple MODULE_BLOCKs in same stream"); + TheModule = M; + if (ParseModule(false)) + return true; + if (LazyStreamer) return false; + break; + default: + if (Stream.SkipBlock()) + return Error("Malformed block record"); + break; + } + continue; + case BitstreamEntry::Record: + // There should be no records in the top-level of blocks. - // The ranlib in xcode 4 will align archive members by appending newlines + // The ranlib in Xcode 4 will align archive members by appending newlines // to the end of them. If this file size is a multiple of 4 but not 8, we // have to read and ignore these final 4 bytes :-( - if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 && + if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && Stream.AtEndOfStream()) return false; return Error("Invalid record at top-level"); } - - unsigned BlockID = Stream.ReadSubBlockID(); - - // We only know the MODULE subblock ID. - switch (BlockID) { - case bitc::BLOCKINFO_BLOCK_ID: - if (Stream.ReadBlockInfoBlock()) - return Error("Malformed BlockInfoBlock"); - break; - case bitc::MODULE_BLOCK_ID: - // Reject multiple MODULE_BLOCK's in a single bitstream. - if (TheModule) - return Error("Multiple MODULE_BLOCKs in same stream"); - TheModule = M; - if (ParseModule(false)) - return true; - if (LazyStreamer) return false; - break; - default: - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; - } } - - return false; } bool BitcodeReader::ParseModuleTriple(std::string &Triple) { @@ -1779,32 +1856,22 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { SmallVector<uint64_t, 64> Record; // Read all the records for this module. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of module block"); + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed module block"); + case BitstreamEntry::EndBlock: return false; - } - - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { - default: // Skip unknown content. - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; - } - continue; - } - - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; @@ -1816,8 +1883,6 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { } Record.clear(); } - - return Error("Premature end of bitstream"); } bool BitcodeReader::ParseTriple(std::string &Triple) { @@ -1834,28 +1899,32 @@ bool BitcodeReader::ParseTriple(std::string &Triple) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); + while (1) { + BitstreamEntry Entry = Stream.advance(); - if (Code != bitc::ENTER_SUBBLOCK) - return Error("Invalid record at top-level"); + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module file"); + return true; + case BitstreamEntry::EndBlock: + return false; - unsigned BlockID = Stream.ReadSubBlockID(); + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return ParseModuleTriple(Triple); - // We only know the MODULE subblock ID. - switch (BlockID) { - case bitc::MODULE_BLOCK_ID: - if (ParseModuleTriple(Triple)) + // Ignore other sub-blocks. + if (Stream.SkipBlock()) { + Error("malformed block record in AST file"); return true; - break; - default: - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; + } + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; } } - - return false; } /// ParseMetadataAttachment - Parse metadata attachments. @@ -1864,20 +1933,23 @@ bool BitcodeReader::ParseMetadataAttachment() { return Error("Malformed block record"); SmallVector<uint64_t, 64> Record; - while(1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed metadata block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. break; } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; - } + // Read a metadata attachment record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: ignore. break; case bitc::METADATA_ATTACHMENT: { @@ -1898,7 +1970,6 @@ bool BitcodeReader::ParseMetadataAttachment() { } } } - return false; } /// ParseFunctionBody - Lazily parse the specified function body block. @@ -1919,19 +1990,20 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { unsigned CurBBNo = 0; DebugLoc LastLoc; - + // Read all the records. SmallVector<uint64_t, 64> Record; while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of function block"); - break; - } + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return Error("Bitcode error in function block"); + case BitstreamEntry::EndBlock: + goto OutOfRecordLoop; - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { + case BitstreamEntry::SubBlock: + switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) return Error("Malformed block record"); @@ -1951,17 +2023,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } continue; - } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); Instruction *I = 0; - unsigned BitCode = Stream.ReadRecord(Code, Record); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); switch (BitCode) { default: // Default behavior: reject return Error("Unknown instruction"); @@ -1974,24 +2045,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()) @@ -2001,10 +2072,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)); @@ -2041,7 +2112,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; } @@ -2272,10 +2358,10 @@ 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(); @@ -2285,17 +2371,17 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { 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) @@ -2311,7 +2397,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; @@ -2319,7 +2405,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(); @@ -2328,9 +2414,9 @@ 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]); @@ -2375,11 +2461,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]); @@ -2534,7 +2620,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 || @@ -2644,7 +2730,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; @@ -2723,6 +2809,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { ValueList.AssignValue(I, NextValueNo++); } +OutOfRecordLoop: + // Check the function list for unresolved values. if (Argument *A = dyn_cast<Argument>(ValueList.back())) { if (A->getParent() == 0) { @@ -2750,15 +2838,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 3d5c0eb..28674eb 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,38 +142,41 @@ 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; + + /// \brief The set of attribute groups. + std::map<unsigned, AttributeSet> MAttributeGroups; + /// FunctionBBs - While parsing a function body, this is a list of the basic /// blocks for the function. std::vector<BasicBlock*> FunctionBBs; - + // When reading the module header, this list is populated with functions that // have bodies later in the file. std::vector<Function*> FunctionsWithBodies; - // When intrinsic functions are encountered which require upgrading they are + // 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; @@ -208,11 +211,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); @@ -224,7 +227,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); @@ -246,12 +249,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. @@ -320,6 +323,7 @@ private: bool ParseModule(bool Resume); bool ParseAttributeBlock(); + bool ParseAttributeGroupBlock(); bool ParseTypeTable(); bool ParseTypeTableBody(); @@ -339,7 +343,7 @@ private: bool FindFunctionInStream(Function *F, DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator); }; - + } // End llvm namespace #endif diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp new file mode 100644 index 0000000..9dafe2a --- /dev/null +++ b/lib/Bitcode/Reader/BitstreamReader.cpp @@ -0,0 +1,371 @@ +//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitstreamReader.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// BitstreamCursor implementation +//===----------------------------------------------------------------------===// + +void BitstreamCursor::operator=(const BitstreamCursor &RHS) { + freeState(); + + BitStream = RHS.BitStream; + NextChar = RHS.NextChar; + CurWord = RHS.CurWord; + BitsInCurWord = RHS.BitsInCurWord; + CurCodeSize = RHS.CurCodeSize; + + // Copy abbreviations, and bump ref counts. + CurAbbrevs = RHS.CurAbbrevs; + for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i) + CurAbbrevs[i]->addRef(); + + // Copy block scope and bump ref counts. + BlockScope = RHS.BlockScope; + for (size_t S = 0, e = BlockScope.size(); S != e; ++S) { + std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; + for (size_t i = 0, e = Abbrevs.size(); i != e; ++i) + Abbrevs[i]->addRef(); + } +} + +void BitstreamCursor::freeState() { + // Free all the Abbrevs. + for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i) + CurAbbrevs[i]->dropRef(); + CurAbbrevs.clear(); + + // Free all the Abbrevs in the block scope. + for (size_t S = 0, e = BlockScope.size(); S != e; ++S) { + std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; + for (size_t i = 0, e = Abbrevs.size(); i != e; ++i) + Abbrevs[i]->dropRef(); + } + BlockScope.clear(); +} + +/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter +/// the block, and return true if the block has an error. +bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { + // Save the current block's state on BlockScope. + BlockScope.push_back(Block(CurCodeSize)); + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); + + // Add the abbrevs specific to this block to the CurAbbrevs list. + if (const BitstreamReader::BlockInfo *Info = + BitStream->getBlockInfo(BlockID)) { + for (size_t i = 0, e = Info->Abbrevs.size(); i != e; ++i) { + CurAbbrevs.push_back(Info->Abbrevs[i]); + CurAbbrevs.back()->addRef(); + } + } + + // Get the codesize of this block. + CurCodeSize = ReadVBR(bitc::CodeLenWidth); + SkipToFourByteBoundary(); + unsigned NumWords = Read(bitc::BlockSizeWidth); + if (NumWordsP) *NumWordsP = NumWords; + + // Validate that this block is sane. + if (CurCodeSize == 0 || AtEndOfStream()) + return true; + + return false; +} + +void BitstreamCursor::readAbbreviatedLiteral(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals) { + assert(Op.isLiteral() && "Not a literal"); + // If the abbrev specifies the literal value to use, use it. + Vals.push_back(Op.getLiteralValue()); +} + +void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals) { + assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + assert(0 && "Should not reach here"); + case BitCodeAbbrevOp::Fixed: + Vals.push_back(Read((unsigned)Op.getEncodingData())); + break; + case BitCodeAbbrevOp::VBR: + Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData())); + break; + case BitCodeAbbrevOp::Char6: + Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6))); + break; + } +} + +void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) { + assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + assert(0 && "Should not reach here"); + case BitCodeAbbrevOp::Fixed: + (void)Read((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::VBR: + (void)ReadVBR64((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::Char6: + (void)Read(6); + break; + } +} + + + +/// skipRecord - Read the current record and discard it. +void BitstreamCursor::skipRecord(unsigned AbbrevID) { + // Skip unabbreviated records by reading past their entries. + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + (void)Code; + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + (void)ReadVBR64(6); + return; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) + continue; + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + skipAbbreviatedField(Op); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + assert(i+2 == e && "array op not second to last?"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + + // Read all the elements. + for (; NumElts; --NumElts) + skipAbbreviatedField(EltEnc); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Skip over the blob. + JumpToBit(NewEnd); + } +} + +unsigned BitstreamCursor::readRecord(unsigned AbbrevID, + SmallVectorImpl<uint64_t> &Vals, + StringRef *Blob) { + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + Vals.push_back(ReadVBR64(6)); + return Code; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) { + readAbbreviatedLiteral(Op, Vals); + continue; + } + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + readAbbreviatedField(Op, Vals); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + assert(i+2 == e && "array op not second to last?"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + + // Read all the elements. + for (; NumElts; --NumElts) + readAbbreviatedField(EltEnc, Vals); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t CurBitPos = GetCurrentBitNo(); + size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + Vals.append(NumElts, 0); + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Otherwise, inform the streamer that we need these bytes in memory. + const char *Ptr = (const char*) + BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts); + + // If we can return a reference to the data, do so to avoid copying it. + if (Blob) { + *Blob = StringRef(Ptr, NumElts); + } else { + // Otherwise, unpack into Vals with zero extension. + for (; NumElts; --NumElts) + Vals.push_back((unsigned char)*Ptr++); + } + // Skip over tail padding. + JumpToBit(NewEnd); + } + + unsigned Code = (unsigned)Vals[0]; + Vals.erase(Vals.begin()); + return Code; +} + + +void BitstreamCursor::ReadAbbrevRecord() { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + unsigned NumOpInfo = ReadVBR(5); + for (unsigned i = 0; i != NumOpInfo; ++i) { + bool IsLiteral = Read(1) ? true : false; + if (IsLiteral) { + Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); + continue; + } + + BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); + if (BitCodeAbbrevOp::hasEncodingData(E)) { + unsigned Data = ReadVBR64(5); + + // As a special case, handle fixed(0) (i.e., a fixed field with zero bits) + // and vbr(0) as a literal zero. This is decoded the same way, and avoids + // a slow path in Read() to have to handle reading zero bits. + if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) && + Data == 0) { + Abbv->Add(BitCodeAbbrevOp(0)); + continue; + } + + Abbv->Add(BitCodeAbbrevOp(E, Data)); + } else + Abbv->Add(BitCodeAbbrevOp(E)); + } + CurAbbrevs.push_back(Abbv); +} + +bool BitstreamCursor::ReadBlockInfoBlock() { + // If this is the second stream to get to the block info block, skip it. + if (BitStream->hasBlockInfoRecords()) + return SkipBlock(); + + if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; + + SmallVector<uint64_t, 64> Record; + BitstreamReader::BlockInfo *CurBlockInfo = 0; + + // Read all the records for this module. + while (1) { + BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs); + + switch (Entry.Kind) { + case llvm::BitstreamEntry::SubBlock: // Handled for us already. + case llvm::BitstreamEntry::Error: + return true; + case llvm::BitstreamEntry::EndBlock: + return false; + case llvm::BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read abbrev records, associate them with CurBID. + if (Entry.ID == bitc::DEFINE_ABBREV) { + if (!CurBlockInfo) return true; + ReadAbbrevRecord(); + + // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the + // appropriate BlockInfo. + BitCodeAbbrev *Abbv = CurAbbrevs.back(); + CurAbbrevs.pop_back(); + CurBlockInfo->Abbrevs.push_back(Abbv); + continue; + } + + // Read a record. + Record.clear(); + switch (readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::BLOCKINFO_CODE_SETBID: + if (Record.size() < 1) return true; + CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]); + break; + case bitc::BLOCKINFO_CODE_BLOCKNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->Name = Name; + break; + } + case bitc::BLOCKINFO_CODE_SETRECORDNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 1, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0], + Name)); + break; + } + } + } +} + diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt index dfe7e10..f614c9f 100644 --- a/lib/Bitcode/Reader/CMakeLists.txt +++ b/lib/Bitcode/Reader/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_library(LLVMBitReader BitReader.cpp BitcodeReader.cpp + BitstreamReader.cpp ) add_dependencies(LLVMBitReader intrinsics_gen) diff --git a/lib/Bitcode/Writer/BitWriter.cpp b/lib/Bitcode/Writer/BitWriter.cpp index 4288422..9f51c35 100644 --- a/lib/Bitcode/Writer/BitWriter.cpp +++ b/lib/Bitcode/Writer/BitWriter.cpp @@ -17,12 +17,11 @@ using namespace llvm; int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) { std::string ErrorInfo; - raw_fd_ostream OS(Path, ErrorInfo, - raw_fd_ostream::F_Binary); - + raw_fd_ostream OS(Path, ErrorInfo, raw_fd_ostream::F_Binary); + if (!ErrorInfo.empty()) return -1; - + WriteBitcodeToFile(unwrap(M), OS); return 0; } @@ -30,7 +29,7 @@ int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) { int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose, int Unbuffered) { raw_fd_ostream OS(FD, ShouldClose, Unbuffered); - + WriteBitcodeToFile(unwrap(M), OS); return 0; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 60c657a..1b73f23 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -12,22 +12,22 @@ //===----------------------------------------------------------------------===// #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Bitcode/BitstreamWriter.h" -#include "llvm/Bitcode/LLVMBitCodes.h" #include "ValueEnumerator.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Operator.h" -#include "llvm/ValueSymbolTable.h" #include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" #include <cctype> #include <map> using namespace llvm; @@ -61,7 +61,7 @@ enum { FUNCTION_INST_RET_VOID_ABBREV, FUNCTION_INST_RET_VAL_ABBREV, FUNCTION_INST_UNREACHABLE_ABBREV, - + // SwitchInst Magic SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; @@ -161,22 +161,66 @@ static void WriteStringRecord(unsigned Code, StringRef Str, Stream.EmitRecord(Code, Vals, AbbrevToUse); } -// Emit information about parameter attributes. +static void WriteAttributeGroupTable(const ValueEnumerator &VE, + BitstreamWriter &Stream) { + const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups(); + if (AttrGrps.empty()) return; + + Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3); + + SmallVector<uint64_t, 64> Record; + for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) { + AttributeSet AS = AttrGrps[i]; + for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) { + AttributeSet A = AS.getSlotAttributes(i); + + Record.push_back(VE.getAttributeGroupID(A)); + Record.push_back(AS.getSlotIndex(i)); + + for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0); + I != E; ++I) { + Attribute Attr = *I; + if (Attr.isEnumAttribute()) { + Record.push_back(0); + Record.push_back(Attr.getKindAsEnum()); + } else if (Attr.isAlignAttribute()) { + Record.push_back(1); + Record.push_back(Attr.getKindAsEnum()); + Record.push_back(Attr.getValueAsInt()); + } else { + StringRef Kind = Attr.getKindAsString(); + StringRef Val = Attr.getValueAsString(); + + Record.push_back(Val.empty() ? 3 : 4); + Record.append(Kind.begin(), Kind.end()); + Record.push_back(0); + if (!Val.empty()) { + Record.append(Val.begin(), Val.end()); + Record.push_back(0); + } + } + } + + Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record); + Record.clear(); + } + } + + Stream.ExitBlock(); +} + static void WriteAttributeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { - const std::vector<AttrListPtr> &Attrs = VE.getAttributes(); + const std::vector<AttributeSet> &Attrs = VE.getAttributes(); if (Attrs.empty()) return; Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); SmallVector<uint64_t, 64> Record; for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { - const AttrListPtr &A = Attrs[i]; - for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) { - const AttributeWithIndex &PAWI = A.getSlot(i); - Record.push_back(PAWI.Index); - Record.push_back(Attributes::encodeLLVMAttributesForBitcode(PAWI.Attrs)); - } + const AttributeSet &A = Attrs[i]; + for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) + Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i))); Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); Record.clear(); @@ -234,7 +278,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); - + // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); @@ -256,16 +300,16 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { switch (T->getTypeID()) { default: llvm_unreachable("Unknown type!"); - case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; - case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; - case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; - case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; - case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; - case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; + case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; + case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; + case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; + case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; + case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; - case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; - case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; - case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; + case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; + case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; case Type::IntegerTyID: // INTEGER: [width] Code = bitc::TYPE_CODE_INTEGER; @@ -300,7 +344,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { for (StructType::element_iterator I = ST->element_begin(), E = ST->element_end(); I != E; ++I) TypeVals.push_back(VE.getTypeID(*I)); - + if (ST->isLiteral()) { Code = bitc::TYPE_CODE_STRUCT_ANON; AbbrevToUse = StructAnonAbbrev; @@ -392,10 +436,6 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) { // descriptors for global variables, and function prototype info. static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) { - // Emit the list of dependent libraries for the Module. - for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) - WriteStringRecord(bitc::MODULE_CODE_DEPLIB, *I, 0/*TODO*/, Stream); - // Emit various pieces of data attached to a module. if (!M->getTargetTriple().empty()) WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), @@ -494,10 +534,11 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0); if (GV->isThreadLocal() || GV->getVisibility() != GlobalValue::DefaultVisibility || - GV->hasUnnamedAddr()) { + GV->hasUnnamedAddr() || GV->isExternallyInitialized()) { Vals.push_back(getEncodedVisibility(GV)); Vals.push_back(getEncodedThreadLocalMode(GV)); Vals.push_back(GV->hasUnnamedAddr()); + Vals.push_back(GV->isExternallyInitialized()); } else { AbbrevToUse = SimpleGVarAbbrev; } @@ -553,6 +594,18 @@ static uint64_t GetOptimizationFlags(const Value *V) { dyn_cast<PossiblyExactOperator>(V)) { if (PEO->isExact()) Flags |= 1 << bitc::PEO_EXACT; + } else if (const FPMathOperator *FPMO = + dyn_cast<const FPMathOperator>(V)) { + if (FPMO->hasUnsafeAlgebra()) + Flags |= FastMathFlags::UnsafeAlgebra; + if (FPMO->hasNoNaNs()) + Flags |= FastMathFlags::NoNaNs; + if (FPMO->hasNoInfs()) + Flags |= FastMathFlags::NoInfs; + if (FPMO->hasNoSignedZeros()) + Flags |= FastMathFlags::NoSignedZeros; + if (FPMO->hasAllowReciprocal()) + Flags |= FastMathFlags::AllowReciprocal; } return Flags; @@ -658,7 +711,7 @@ static void WriteFunctionLocalMetadata(const Function &F, } WriteMDNode(N, VE, Stream, Record); } - + if (StartedMetadataBlock) Stream.ExitBlock(); } @@ -673,18 +726,18 @@ static void WriteMetadataAttachment(const Function &F, // Write metadata attachments // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] SmallVector<std::pair<unsigned, MDNode*>, 4> MDs; - + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { MDs.clear(); I->getAllMetadataOtherThanDebugLoc(MDs); - + // If no metadata, ignore instruction. if (MDs.empty()) continue; Record.push_back(VE.getInstructionID(I)); - + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { Record.push_back(MDs[i].first); Record.push_back(VE.getValueID(MDs[i].second)); @@ -701,18 +754,18 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { // Write metadata kinds // METADATA_KIND - [n x [id, name]] - SmallVector<StringRef, 4> Names; + SmallVector<StringRef, 8> Names; M->getMDKindNames(Names); - + if (Names.empty()) return; Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - + for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { Record.push_back(MDKindID); StringRef KName = Names[MDKindID]; Record.append(KName.begin(), KName.end()); - + Stream.EmitRecord(bitc::METADATA_KIND, Record, 0); Record.clear(); } @@ -743,10 +796,10 @@ static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals, // format it is likely that the high bits are going to be zero. // So, we only write the number of active words. unsigned NWords = Val.getActiveWords(); - + if (EmitSizeForWideNumbers) Vals.push_back(NWords); - + const uint64_t *RawWords = Val.getRawData(); for (unsigned i = 0; i != NWords; ++i) { emitSignedInt64(Vals, RawWords[i]); @@ -881,12 +934,12 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, if (isCStrChar6) isCStrChar6 = BitCodeAbbrevOp::isChar6(V); } - + if (isCStrChar6) AbbrevToUse = CString6Abbrev; else if (isCStr7) AbbrevToUse = CString7Abbrev; - } else if (const ConstantDataSequential *CDS = + } else if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) { Code = bitc::CST_CODE_DATA; Type *EltTy = CDS->getType()->getElementType(); @@ -1166,7 +1219,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::Br: { Code = bitc::FUNC_CODE_INST_BR; - BranchInst &II = cast<BranchInst>(I); + const BranchInst &II = cast<BranchInst>(I); Vals.push_back(VE.getValueID(II.getSuccessor(0))); if (II.isConditional()) { Vals.push_back(VE.getValueID(II.getSuccessor(1))); @@ -1179,36 +1232,36 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, // Redefine Vals, since here we need to use 64 bit values // explicitly to store large APInt numbers. SmallVector<uint64_t, 128> Vals64; - + Code = bitc::FUNC_CODE_INST_SWITCH; - SwitchInst &SI = cast<SwitchInst>(I); - - uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16); - Vals64.push_back(SwitchRecordHeader); - + const SwitchInst &SI = cast<SwitchInst>(I); + + uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16); + Vals64.push_back(SwitchRecordHeader); + Vals64.push_back(VE.getTypeID(SI.getCondition()->getType())); pushValue64(SI.getCondition(), InstID, Vals64, VE); Vals64.push_back(VE.getValueID(SI.getDefaultDest())); Vals64.push_back(SI.getNumCases()); - for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); + for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { - IntegersSubset& CaseRanges = i.getCaseValueEx(); + const IntegersSubset& CaseRanges = i.getCaseValueEx(); unsigned Code, Abbrev; // will unused. - + if (CaseRanges.isSingleNumber()) { Vals64.push_back(1/*NumItems = 1*/); Vals64.push_back(true/*IsSingleNumber = true*/); EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true); } else { - + Vals64.push_back(CaseRanges.getNumItems()); - + if (CaseRanges.isSingleNumbersOnly()) { for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) { - + Vals64.push_back(true/*IsSingleNumber = true*/); - + EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(ri), true); } @@ -1217,9 +1270,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, ri != rn; ++ri) { IntegersSubset::Range r = CaseRanges.getItem(ri); bool IsSingleNumber = CaseRanges.isSingleNumber(ri); - + Vals64.push_back(IsSingleNumber); - + EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true); if (!IsSingleNumber) EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true); @@ -1227,9 +1280,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } Vals64.push_back(VE.getValueID(i.getCaseSuccessor())); } - + Stream.EmitRecord(Code, Vals64, AbbrevToUse); - + // Also do expected action - clear external Vals collection: Vals.clear(); return; @@ -1243,7 +1296,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) Vals.push_back(VE.getValueID(I.getOperand(i))); break; - + case Instruction::Invoke: { const InvokeInst *II = cast<InvokeInst>(&I); const Value *Callee(II->getCalledValue()); @@ -1502,21 +1555,21 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, unsigned InstID = CstEnd; bool NeedsMetadataAttachment = false; - + DebugLoc LastDL; - + // Finally, emit all the instructions, in order. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { WriteInstruction(*I, InstID, VE, Stream, Vals); - + if (!I->getType()->isVoidTy()) ++InstID; - + // If the instruction has metadata, write a metadata attachment later. NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc(); - + // If the instruction has a debug location, emit it. DebugLoc DL = I->getDebugLoc(); if (DL.isUnknown()) { @@ -1527,14 +1580,14 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, } else { MDNode *Scope, *IA; DL.getScopeAndInlinedAt(Scope, IA, I->getContext()); - + Vals.push_back(DL.getLine()); Vals.push_back(DL.getCol()); Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0); Vals.push_back(IA ? VE.getValueID(IA)+1 : 0); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); - + LastDL = DL; } } @@ -1709,7 +1762,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { Stream.ExitBlock(); } -// Sort the Users based on the order in which the reader parses the bitcode +// Sort the Users based on the order in which the reader parses the bitcode // file. static bool bitcodereader_order(const User *lhs, const User *rhs) { // TODO: Implement. @@ -1778,9 +1831,9 @@ static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE, for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) I->removeDeadConstantUsers(); - + // Write the global variables. - for (Module::const_global_iterator GI = M->global_begin(), + for (Module::const_global_iterator GI = M->global_begin(), GE = M->global_end(); GI != GE; ++GI) { WriteUseList(GI, VE, Stream); @@ -1821,6 +1874,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { // Emit blockinfo, which defines the standard abbreviations etc. WriteBlockInfo(VE, Stream); + // Emit information about attribute groups. + WriteAttributeGroupTable(VE, Stream); + // Emit information about parameter attributes. WriteAttributeTable(VE, Stream); @@ -1931,7 +1987,7 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer, /// WriteBitcodeToFile - Write the specified module to the specified output /// stream. void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { - SmallVector<char, 1024> Buffer; + SmallVector<char, 0> Buffer; Buffer.reserve(256*1024); // If this is darwin or another generic macho target, reserve space for the diff --git a/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/lib/Bitcode/Writer/BitcodeWriterPass.cpp index 91e115c..e5e76e2 100644 --- a/lib/Bitcode/Writer/BitcodeWriterPass.cpp +++ b/lib/Bitcode/Writer/BitcodeWriterPass.cpp @@ -22,9 +22,9 @@ namespace { static char ID; // Pass identification, replacement for typeid explicit WriteBitcodePass(raw_ostream &o) : ModulePass(ID), OS(o) {} - + const char *getPassName() const { return "Bitcode Writer"; } - + bool runOnModule(Module &M) { WriteBitcodeToFile(&M, OS); return false; diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 1ed9004..8bac6da 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -12,20 +12,20 @@ //===----------------------------------------------------------------------===// #include "ValueEnumerator.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/ValueSymbolTable.h" -#include "llvm/Instructions.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> using namespace llvm; -static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) { - return V.first->getType()->isIntegerTy(); +static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { + return V.first->getType()->isIntOrIntVectorTy(); } /// ValueEnumerator - Enumerate module-level information. @@ -60,7 +60,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) { I != E; ++I) EnumerateValue(I->getAliasee()); - // Insert constants and metadata that are named at module level into the slot + // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M->getValueSymbolTable()); EnumerateNamedMetadata(M); @@ -95,7 +95,7 @@ ValueEnumerator::ValueEnumerator(const Module *M) { I->getAllMetadataOtherThanDebugLoc(MDs); for (unsigned i = 0, e = MDs.size(); i != e; ++i) EnumerateMetadata(MDs[i].second); - + if (!I->getDebugLoc().isUnknown()) { MDNode *Scope, *IA; I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext()); @@ -192,10 +192,11 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { CstSortPredicate P(*this); std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P); - // Ensure that integer constants are at the start of the constant pool. This - // is important so that GEP structure indices come before gep constant exprs. + // Ensure that integer and vector of integer constants are at the start of the + // constant pool. This is important so that GEP structure indices come before + // gep constant exprs. std::partition(Values.begin()+CstStart, Values.begin()+CstEnd, - isIntegerValue); + isIntOrIntVectorValue); // Rebuild the modified portion of ValueMap. for (; CstStart != CstEnd; ++CstStart) @@ -362,16 +363,16 @@ void ValueEnumerator::EnumerateType(Type *Ty) { if (StructType *STy = dyn_cast<StructType>(Ty)) if (!STy->isLiteral()) *TypeID = ~0U; - + // Enumerate all of the subtypes before we enumerate this type. This ensures // that the type will be enumerated in an order that can be directly built. for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) EnumerateType(*I); - + // Refresh the TypeID pointer in case the table rehashed. TypeID = &TypeMap[Ty]; - + // Check to see if we got the pointer another way. This can happen when // enumerating recursive types that hit the base case deeper than they start. // @@ -379,10 +380,10 @@ void ValueEnumerator::EnumerateType(Type *Ty) { // then emit the definition now that all of its contents are available. if (*TypeID && *TypeID != ~0U) return; - + // Add this type now that its contents are all happily enumerated. Types.push_back(Ty); - + *TypeID = Types.size(); } @@ -390,7 +391,7 @@ void ValueEnumerator::EnumerateType(Type *Ty) { // walk through it, enumerating the types of the constant. void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateType(V->getType()); - + if (const Constant *C = dyn_cast<Constant>(V)) { // If this constant is already enumerated, ignore it, we know its type must // be enumerated. @@ -400,11 +401,11 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) { // them. for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { const Value *Op = C->getOperand(i); - + // Don't enumerate basic blocks here, this happens as operands to // blockaddress. if (isa<BasicBlock>(Op)) continue; - + EnumerateOperandType(Op); } @@ -417,14 +418,25 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateMetadata(V); } -void ValueEnumerator::EnumerateAttributes(const AttrListPtr &PAL) { +void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { if (PAL.isEmpty()) return; // null is always 0. + // Do a lookup. - unsigned &Entry = AttributeMap[PAL.getRawPointer()]; + unsigned &Entry = AttributeMap[PAL]; if (Entry == 0) { // Never saw this before, add it. - Attributes.push_back(PAL); - Entry = Attributes.size(); + Attribute.push_back(PAL); + Entry = Attribute.size(); + } + + // Do lookups for all attribute groups. + for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) { + AttributeSet AS = PAL.getSlotAttributes(i); + unsigned &Entry = AttributeGroupMap[AS]; + if (Entry == 0) { + AttributeGroups.push_back(AS); + Entry = AttributeGroups.size(); + } } } @@ -481,7 +493,7 @@ void ValueEnumerator::incorporateFunction(const Function &F) { if (N->isFunctionLocal() && N->getFunction()) FnLocalMDVector.push_back(N); } - + if (!I->getType()->isVoidTy()) EnumerateValue(I); } diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index 75468e6..0af6164c 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -16,7 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Attributes.h" +#include "llvm/IR/Attributes.h" #include <vector> namespace llvm { @@ -29,7 +29,7 @@ class Function; class Module; class MDNode; class NamedMDNode; -class AttrListPtr; +class AttributeSet; class ValueSymbolTable; class MDSymbolTable; class raw_ostream; @@ -51,15 +51,19 @@ private: ValueList MDValues; SmallVector<const MDNode *, 8> FunctionLocalMDs; ValueMapType MDValueMap; - - typedef DenseMap<void*, unsigned> AttributeMapType; + + typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType; + AttributeGroupMapType AttributeGroupMap; + std::vector<AttributeSet> AttributeGroups; + + typedef DenseMap<AttributeSet, unsigned> AttributeMapType; AttributeMapType AttributeMap; - std::vector<AttrListPtr> Attributes; - + std::vector<AttributeSet> Attribute; + /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by /// the "getGlobalBasicBlockID" method. mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs; - + typedef DenseMap<const Instruction*, unsigned> InstructionMapType; InstructionMapType InstructionMap; unsigned InstructionCount; @@ -67,7 +71,7 @@ private: /// BasicBlocks - This contains all the basic blocks for the currently /// incorporated function. Their reverse mapping is stored in ValueMap. std::vector<const BasicBlock*> BasicBlocks; - + /// When a function is incorporated, this is the size of the Values list /// before incorporation. unsigned NumModuleValues; @@ -98,33 +102,43 @@ public: unsigned getInstructionID(const Instruction *I) const; void setInstructionID(const Instruction *I); - unsigned getAttributeID(const AttrListPtr &PAL) const { + unsigned getAttributeID(AttributeSet PAL) const { if (PAL.isEmpty()) return 0; // Null maps to zero. - AttributeMapType::const_iterator I = AttributeMap.find(PAL.getRawPointer()); + AttributeMapType::const_iterator I = AttributeMap.find(PAL); assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!"); return I->second; } + unsigned getAttributeGroupID(AttributeSet PAL) const { + if (PAL.isEmpty()) return 0; // Null maps to zero. + AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL); + assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!"); + return I->second; + } + /// getFunctionConstantRange - Return the range of values that corresponds to /// function-local constants. void getFunctionConstantRange(unsigned &Start, unsigned &End) const { Start = FirstFuncConstantID; End = FirstInstID; } - + const ValueList &getValues() const { return Values; } const ValueList &getMDValues() const { return MDValues; } - const SmallVector<const MDNode *, 8> &getFunctionLocalMDValues() const { + const SmallVector<const MDNode *, 8> &getFunctionLocalMDValues() const { return FunctionLocalMDs; } const TypeList &getTypes() const { return Types; } const std::vector<const BasicBlock*> &getBasicBlocks() const { - return BasicBlocks; + return BasicBlocks; + } + const std::vector<AttributeSet> &getAttributes() const { + return Attribute; } - const std::vector<AttrListPtr> &getAttributes() const { - return Attributes; + const std::vector<AttributeSet> &getAttributeGroups() const { + return AttributeGroups; } - + /// getGlobalBasicBlockID - This returns the function-specific ID for the /// specified basic block. This is relatively expensive information, so it /// should only be used by rare constructs such as address-of-label. @@ -138,7 +152,7 @@ public: private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); - + void EnumerateMDNodeOperands(const MDNode *N); void EnumerateMetadata(const Value *MD); void EnumerateFunctionLocalMetadata(const MDNode *N); @@ -146,8 +160,8 @@ private: void EnumerateValue(const Value *V); void EnumerateType(Type *T); void EnumerateOperandType(const Value *V); - void EnumerateAttributes(const AttrListPtr &PAL); - + void EnumerateAttributes(AttributeSet PAL); + void EnumerateValueSymbolTable(const ValueSymbolTable &ST); void EnumerateNamedMetadata(const Module *M); }; |