summaryrefslogtreecommitdiffstats
path: root/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp571
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h28
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp199
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp114
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h3
5 files changed, 470 insertions, 445 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index bc995ae..24c2994 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -31,7 +31,7 @@ void BitcodeReader::FreeState() {
if (BufferOwned)
delete Buffer;
Buffer = 0;
- std::vector<PATypeHolder>().swap(TypeList);
+ std::vector<Type*>().swap(TypeList);
ValueList.clear();
MDValueList.clear();
@@ -292,11 +292,9 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
// Make the new constant.
Constant *NewC;
if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) {
- NewC = ConstantArray::get(UserCA->getType(), &NewOps[0],
- NewOps.size());
+ NewC = ConstantArray::get(UserCA->getType(), NewOps);
} else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
- NewC = ConstantStruct::get(Context, &NewOps[0], NewOps.size(),
- UserCS->getType()->isPacked());
+ NewC = ConstantStruct::get(UserCS->getType(), NewOps);
} else if (isa<ConstantVector>(UserC)) {
NewC = ConstantVector::get(NewOps);
} else {
@@ -354,19 +352,28 @@ Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
return V;
}
-const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
- // If the TypeID is in range, return it.
- if (ID < TypeList.size())
- return TypeList[ID].get();
- if (!isTypeTable) return 0;
-
- // The type table allows forward references. Push as many Opaque types as
- // needed to get up to ID.
- while (TypeList.size() <= ID)
- TypeList.push_back(OpaqueType::get(Context));
- return TypeList.back().get();
+Type *BitcodeReader::getTypeByID(unsigned ID) {
+ // The type table size is always specified correctly.
+ if (ID >= TypeList.size())
+ return 0;
+
+ if (Type *Ty = TypeList[ID])
+ return Ty;
+
+ // If we have a forward reference, the only possible case is when it is to a
+ // named struct. Just create a placeholder for now.
+ return TypeList[ID] = StructType::createNamed(Context, "");
}
+/// FIXME: Remove in LLVM 3.1, only used by ParseOldTypeTable.
+Type *BitcodeReader::getTypeByIDOrNull(unsigned ID) {
+ if (ID >= TypeList.size())
+ TypeList.resize(ID+1);
+
+ return TypeList[ID];
+}
+
+
//===----------------------------------------------------------------------===//
// Functions for parsing blocks from the bitcode file
//===----------------------------------------------------------------------===//
@@ -473,17 +480,22 @@ bool BitcodeReader::ParseAttributeBlock() {
}
}
-
bool BitcodeReader::ParseTypeTable() {
- if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID))
+ if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
return Error("Malformed block record");
+
+ return ParseTypeTableBody();
+}
+bool BitcodeReader::ParseTypeTableBody() {
if (!TypeList.empty())
return Error("Multiple TYPE_BLOCKs found!");
SmallVector<uint64_t, 64> Record;
unsigned NumRecords = 0;
+ SmallString<64> TypeName;
+
// Read all the records for this type table.
while (1) {
unsigned Code = Stream.ReadCode();
@@ -510,17 +522,15 @@ bool BitcodeReader::ParseTypeTable() {
// Read a record.
Record.clear();
- const Type *ResultTy = 0;
+ Type *ResultTy = 0;
switch (Stream.ReadRecord(Code, Record)) {
- default: // Default behavior: unknown type.
- ResultTy = 0;
- break;
+ 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
// type list. This allows us to reserve space.
if (Record.size() < 1)
return Error("Invalid TYPE_CODE_NUMENTRY record");
- TypeList.reserve(Record[0]);
+ TypeList.resize(Record[0]);
continue;
case bitc::TYPE_CODE_VOID: // VOID
ResultTy = Type::getVoidTy(Context);
@@ -543,9 +553,6 @@ bool BitcodeReader::ParseTypeTable() {
case bitc::TYPE_CODE_LABEL: // LABEL
ResultTy = Type::getLabelTy(Context);
break;
- case bitc::TYPE_CODE_OPAQUE: // OPAQUE
- ResultTy = 0;
- break;
case bitc::TYPE_CODE_METADATA: // METADATA
ResultTy = Type::getMetadataTy(Context);
break;
@@ -565,8 +572,9 @@ bool BitcodeReader::ParseTypeTable() {
unsigned AddressSpace = 0;
if (Record.size() == 2)
AddressSpace = Record[1];
- ResultTy = PointerType::get(getTypeByID(Record[0], true),
- AddressSpace);
+ ResultTy = getTypeByID(Record[0]);
+ if (ResultTy == 0) return Error("invalid element type in pointer type");
+ ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
}
case bitc::TYPE_CODE_FUNCTION: {
@@ -574,69 +582,306 @@ bool BitcodeReader::ParseTypeTable() {
// FUNCTION: [vararg, attrid, retty, paramty x N]
if (Record.size() < 3)
return Error("Invalid FUNCTION type record");
- std::vector<const Type*> ArgTys;
- for (unsigned i = 3, e = Record.size(); i != e; ++i)
- ArgTys.push_back(getTypeByID(Record[i], true));
+ std::vector<Type*> ArgTys;
+ for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ ArgTys.push_back(T);
+ else
+ break;
+ }
+
+ ResultTy = getTypeByID(Record[2]);
+ if (ResultTy == 0 || ArgTys.size() < Record.size()-3)
+ return Error("invalid type in function type");
- ResultTy = FunctionType::get(getTypeByID(Record[2], true), ArgTys,
- Record[0]);
+ ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
break;
}
- case bitc::TYPE_CODE_STRUCT: { // STRUCT: [ispacked, eltty x N]
+ case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N]
if (Record.size() < 1)
return Error("Invalid STRUCT type record");
- std::vector<const Type*> EltTys;
- for (unsigned i = 1, e = Record.size(); i != e; ++i)
- EltTys.push_back(getTypeByID(Record[i], true));
+ std::vector<Type*> EltTys;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ EltTys.push_back(T);
+ else
+ break;
+ }
+ if (EltTys.size() != Record.size()-1)
+ return Error("invalid type in struct type");
ResultTy = StructType::get(Context, EltTys, Record[0]);
break;
}
+ case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N]
+ if (ConvertToString(Record, 0, TypeName))
+ return Error("Invalid STRUCT_NAME record");
+ continue;
+
+ 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) {
+ Res->setName(TypeName);
+ TypeList[NumRecords] = 0;
+ } else // Otherwise, create a new struct.
+ Res = StructType::createNamed(Context, TypeName);
+ TypeName.clear();
+
+ SmallVector<Type*, 8> EltTys;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+ if (Type *T = getTypeByID(Record[i]))
+ EltTys.push_back(T);
+ else
+ break;
+ }
+ if (EltTys.size() != Record.size()-1)
+ return Error("invalid STRUCT type record");
+ Res->setBody(EltTys, Record[0]);
+ ResultTy = Res;
+ break;
+ }
+ case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: []
+ if (Record.size() != 1)
+ return Error("Invalid OPAQUE 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) {
+ Res->setName(TypeName);
+ TypeList[NumRecords] = 0;
+ } else // Otherwise, create a new struct with no body.
+ Res = StructType::createNamed(Context, TypeName);
+ TypeName.clear();
+ ResultTy = Res;
+ break;
+ }
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
- ResultTy = ArrayType::get(getTypeByID(Record[1], true), Record[0]);
+ if ((ResultTy = getTypeByID(Record[1])))
+ ResultTy = ArrayType::get(ResultTy, Record[0]);
+ else
+ return Error("Invalid ARRAY type element");
break;
case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid VECTOR type record");
- ResultTy = VectorType::get(getTypeByID(Record[1], true), Record[0]);
+ if ((ResultTy = getTypeByID(Record[1])))
+ ResultTy = VectorType::get(ResultTy, Record[0]);
+ else
+ return Error("Invalid ARRAY type element");
break;
}
- if (NumRecords == TypeList.size()) {
- // If this is a new type slot, just append it.
- TypeList.push_back(ResultTy ? ResultTy : OpaqueType::get(Context));
- ++NumRecords;
- } else if (ResultTy == 0) {
- // Otherwise, this was forward referenced, so an opaque type was created,
- // but the result type is actually just an opaque. Leave the one we
- // created previously.
- ++NumRecords;
- } else {
- // Otherwise, this was forward referenced, so an opaque type was created.
- // Resolve the opaque type to the real type now.
- assert(NumRecords < TypeList.size() && "Typelist imbalance");
- const OpaqueType *OldTy = cast<OpaqueType>(TypeList[NumRecords++].get());
-
- // Don't directly push the new type on the Tab. Instead we want to replace
- // the opaque type we previously inserted with the new concrete value. The
- // refinement from the abstract (opaque) type to the new type causes all
- // uses of the abstract type to use the concrete type (NewTy). This will
- // also cause the opaque type to be deleted.
- const_cast<OpaqueType*>(OldTy)->refineAbstractTypeTo(ResultTy);
-
- // This should have replaced the old opaque type with the new type in the
- // value table... or with a preexisting type that was already in the
- // system. Let's just make sure it did.
- assert(TypeList[NumRecords-1].get() != OldTy &&
- "refineAbstractType didn't work!");
+ if (NumRecords >= TypeList.size())
+ return Error("invalid TYPE table");
+ assert(ResultTy && "Didn't read a type?");
+ assert(TypeList[NumRecords] == 0 && "Already read type?");
+ TypeList[NumRecords++] = ResultTy;
+ }
+}
+
+// FIXME: Remove in LLVM 3.1
+bool BitcodeReader::ParseOldTypeTable() {
+ if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_OLD))
+ return Error("Malformed block record");
+
+ if (!TypeList.empty())
+ return Error("Multiple TYPE_BLOCKs found!");
+
+
+ // While horrible, we have no good ordering of types in the bc file. Just
+ // iteratively parse types out of the bc file in multiple passes until we get
+ // them all. Do this by saving a cursor for the start of the type block.
+ BitstreamCursor StartOfTypeBlockCursor(Stream);
+
+ unsigned NumTypesRead = 0;
+
+ SmallVector<uint64_t, 64> Record;
+RestartScan:
+ unsigned NextTypeID = 0;
+ bool ReadAnyTypes = false;
+
+ // Read all the records for this type table.
+ while (1) {
+ unsigned Code = Stream.ReadCode();
+ if (Code == bitc::END_BLOCK) {
+ if (NextTypeID != TypeList.size())
+ return Error("Invalid type forward reference in TYPE_BLOCK_ID_OLD");
+
+ // If we haven't read all of the types yet, iterate again.
+ if (NumTypesRead != TypeList.size()) {
+ // If we didn't successfully read any types in this pass, then we must
+ // have an unhandled forward reference.
+ if (!ReadAnyTypes)
+ return Error("Obsolete bitcode contains unhandled recursive type");
+
+ Stream = StartOfTypeBlockCursor;
+ goto RestartScan;
+ }
+
+ 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;
}
+
+ // Read a record.
+ Record.clear();
+ Type *ResultTy = 0;
+ switch (Stream.ReadRecord(Code, 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
+ // type list. This allows us to reserve space.
+ if (Record.size() < 1)
+ return Error("Invalid TYPE_CODE_NUMENTRY record");
+ TypeList.resize(Record[0]);
+ continue;
+ case bitc::TYPE_CODE_VOID: // VOID
+ ResultTy = Type::getVoidTy(Context);
+ break;
+ case bitc::TYPE_CODE_FLOAT: // FLOAT
+ ResultTy = Type::getFloatTy(Context);
+ break;
+ case bitc::TYPE_CODE_DOUBLE: // DOUBLE
+ ResultTy = Type::getDoubleTy(Context);
+ break;
+ case bitc::TYPE_CODE_X86_FP80: // X86_FP80
+ ResultTy = Type::getX86_FP80Ty(Context);
+ break;
+ case bitc::TYPE_CODE_FP128: // FP128
+ ResultTy = Type::getFP128Ty(Context);
+ break;
+ case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+ ResultTy = Type::getPPC_FP128Ty(Context);
+ break;
+ case bitc::TYPE_CODE_LABEL: // LABEL
+ ResultTy = Type::getLabelTy(Context);
+ break;
+ case bitc::TYPE_CODE_METADATA: // METADATA
+ ResultTy = Type::getMetadataTy(Context);
+ break;
+ case bitc::TYPE_CODE_X86_MMX: // X86_MMX
+ ResultTy = Type::getX86_MMXTy(Context);
+ break;
+ case bitc::TYPE_CODE_INTEGER: // INTEGER: [width]
+ if (Record.size() < 1)
+ return Error("Invalid Integer type record");
+ ResultTy = IntegerType::get(Context, Record[0]);
+ break;
+ case bitc::TYPE_CODE_OPAQUE: // OPAQUE
+ if (NextTypeID < TypeList.size() && TypeList[NextTypeID] == 0)
+ ResultTy = StructType::createNamed(Context, "");
+ break;
+ case bitc::TYPE_CODE_STRUCT_OLD: {// STRUCT_OLD
+ if (NextTypeID >= TypeList.size()) break;
+ // If we already read it, don't reprocess.
+ if (TypeList[NextTypeID] &&
+ !cast<StructType>(TypeList[NextTypeID])->isOpaque())
+ break;
+
+ // Set a type.
+ if (TypeList[NextTypeID] == 0)
+ TypeList[NextTypeID] = StructType::createNamed(Context, "");
+
+ std::vector<Type*> EltTys;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+ if (Type *Elt = getTypeByIDOrNull(Record[i]))
+ EltTys.push_back(Elt);
+ else
+ break;
+ }
+
+ if (EltTys.size() != Record.size()-1)
+ break; // Not all elements are ready.
+
+ cast<StructType>(TypeList[NextTypeID])->setBody(EltTys, Record[0]);
+ ResultTy = TypeList[NextTypeID];
+ TypeList[NextTypeID] = 0;
+ break;
+ }
+ case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+ // [pointee type, address space]
+ if (Record.size() < 1)
+ return Error("Invalid POINTER type record");
+ unsigned AddressSpace = 0;
+ if (Record.size() == 2)
+ AddressSpace = Record[1];
+ if ((ResultTy = getTypeByIDOrNull(Record[0])))
+ ResultTy = PointerType::get(ResultTy, AddressSpace);
+ break;
+ }
+ case bitc::TYPE_CODE_FUNCTION: {
+ // FIXME: attrid is dead, remove it in LLVM 3.0
+ // FUNCTION: [vararg, attrid, retty, paramty x N]
+ if (Record.size() < 3)
+ return Error("Invalid FUNCTION type record");
+ std::vector<Type*> ArgTys;
+ for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+ if (Type *Elt = getTypeByIDOrNull(Record[i]))
+ ArgTys.push_back(Elt);
+ else
+ break;
+ }
+ if (ArgTys.size()+3 != Record.size())
+ break; // Something was null.
+ if ((ResultTy = getTypeByIDOrNull(Record[2])))
+ ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+ break;
+ }
+ case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
+ if (Record.size() < 2)
+ return Error("Invalid ARRAY type record");
+ if ((ResultTy = getTypeByIDOrNull(Record[1])))
+ ResultTy = ArrayType::get(ResultTy, Record[0]);
+ break;
+ case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
+ if (Record.size() < 2)
+ return Error("Invalid VECTOR type record");
+ if ((ResultTy = getTypeByIDOrNull(Record[1])))
+ ResultTy = VectorType::get(ResultTy, Record[0]);
+ break;
+ }
+
+ if (NextTypeID >= TypeList.size())
+ return Error("invalid TYPE table");
+
+ if (ResultTy && TypeList[NextTypeID] == 0) {
+ ++NumTypesRead;
+ ReadAnyTypes = true;
+
+ TypeList[NextTypeID] = ResultTy;
+ }
+
+ ++NextTypeID;
}
}
-bool BitcodeReader::ParseTypeSymbolTable() {
- if (Stream.EnterSubBlock(bitc::TYPE_SYMTAB_BLOCK_ID))
+bool BitcodeReader::ParseOldTypeSymbolTable() {
+ if (Stream.EnterSubBlock(bitc::TYPE_SYMTAB_BLOCK_ID_OLD))
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
@@ -676,7 +921,10 @@ bool BitcodeReader::ParseTypeSymbolTable() {
if (TypeID >= TypeList.size())
return Error("Invalid Type ID in TST_ENTRY record");
- TheModule->addTypeName(TypeName, TypeList[TypeID].get());
+ // Only apply the type name to a struct type with no name.
+ if (StructType *STy = dyn_cast<StructType>(TypeList[TypeID]))
+ if (!STy->isAnonymous() && !STy->hasName())
+ STy->setName(TypeName);
TypeName.clear();
break;
}
@@ -790,13 +1038,9 @@ bool BitcodeReader::ParseMetadata() {
Record.clear();
Code = Stream.ReadCode();
- // METADATA_NAME is always followed by METADATA_NAMED_NODE2.
- // Or METADATA_NAMED_NODE in LLVM 2.7. FIXME: Remove this in LLVM 3.0.
+ // METADATA_NAME is always followed by METADATA_NAMED_NODE.
unsigned NextBitCode = Stream.ReadRecord(Code, Record);
- if (NextBitCode == bitc::METADATA_NAMED_NODE) {
- LLVM2_7MetadataDetected = true;
- } else if (NextBitCode != bitc::METADATA_NAMED_NODE2)
- assert ( 0 && "Invalid Named Metadata record");
+ assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode;
// Read named metadata elements.
unsigned Size = Record.size();
@@ -807,35 +1051,20 @@ bool BitcodeReader::ParseMetadata() {
return Error("Malformed metadata record");
NMD->addOperand(MD);
}
- // Backwards compatibility hack: NamedMDValues used to be Values,
- // and they got their own slots in the value numbering. They are no
- // longer Values, however we still need to account for them in the
- // numbering in order to be able to read old bitcode files.
- // FIXME: Remove this in LLVM 3.0.
- if (LLVM2_7MetadataDetected)
- MDValueList.AssignValue(0, NextMDValueNo++);
break;
}
- case bitc::METADATA_FN_NODE: // FIXME: Remove in LLVM 3.0.
- case bitc::METADATA_FN_NODE2:
+ case bitc::METADATA_FN_NODE:
IsFunctionLocal = true;
// fall-through
- case bitc::METADATA_NODE: // FIXME: Remove in LLVM 3.0.
- case bitc::METADATA_NODE2: {
-
- // Detect 2.7-era metadata.
- // FIXME: Remove in LLVM 3.0.
- if (Code == bitc::METADATA_FN_NODE || Code == bitc::METADATA_NODE)
- LLVM2_7MetadataDetected = true;
-
+ case bitc::METADATA_NODE: {
if (Record.size() % 2 == 1)
- return Error("Invalid METADATA_NODE2 record");
+ return Error("Invalid METADATA_NODE record");
unsigned Size = Record.size();
SmallVector<Value*, 8> Elts;
for (unsigned i = 0; i != Size; i += 2) {
const Type *Ty = getTypeByID(Record[i]);
- if (!Ty) return Error("Invalid METADATA_NODE2 record");
+ if (!Ty) return Error("Invalid METADATA_NODE record");
if (Ty->isMetadataTy())
Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
else if (!Ty->isVoidTy())
@@ -1331,12 +1560,16 @@ bool BitcodeReader::ParseModule() {
if (ParseAttributeBlock())
return true;
break;
- case bitc::TYPE_BLOCK_ID:
+ case bitc::TYPE_BLOCK_ID_NEW:
if (ParseTypeTable())
return true;
break;
- case bitc::TYPE_SYMTAB_BLOCK_ID:
- if (ParseTypeSymbolTable())
+ case bitc::TYPE_BLOCK_ID_OLD:
+ if (ParseOldTypeTable())
+ return true;
+ break;
+ case bitc::TYPE_SYMTAB_BLOCK_ID_OLD:
+ if (ParseOldTypeSymbolTable())
return true;
break;
case bitc::VALUE_SYMTAB_BLOCK_ID:
@@ -1755,10 +1988,7 @@ bool BitcodeReader::ParseMetadataAttachment() {
switch (Stream.ReadRecord(Code, Record)) {
default: // Default behavior: ignore.
break;
- // FIXME: Remove in LLVM 3.0.
- case bitc::METADATA_ATTACHMENT:
- LLVM2_7MetadataDetected = true;
- case bitc::METADATA_ATTACHMENT2: {
+ case bitc::METADATA_ATTACHMENT: {
unsigned RecordLength = Record.size();
if (Record.empty() || (RecordLength - 1) % 2 == 1)
return Error ("Invalid METADATA_ATTACHMENT reader!");
@@ -1870,10 +2100,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
I = 0;
continue;
- // FIXME: Remove this in LLVM 3.0.
- case bitc::FUNC_CODE_DEBUG_LOC:
- LLVM2_7MetadataDetected = true;
- case bitc::FUNC_CODE_DEBUG_LOC2: { // DEBUG_LOC: [line, col, scope, ia]
+ case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
I = 0; // Get the last instruction emitted.
if (CurBB && !CurBB->empty())
I = &CurBB->back();
@@ -1979,8 +2206,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
EXTRACTVALIdx.push_back((unsigned)Index);
}
- I = ExtractValueInst::Create(Agg,
- EXTRACTVALIdx.begin(), EXTRACTVALIdx.end());
+ I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
InstructionList.push_back(I);
break;
}
@@ -2004,8 +2230,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
INSERTVALIdx.push_back((unsigned)Index);
}
- I = InsertValueInst::Create(Agg, Val,
- INSERTVALIdx.begin(), INSERTVALIdx.end());
+ I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
InstructionList.push_back(I);
break;
}
@@ -2112,18 +2337,6 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break;
}
- case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n]
- if (Record.size() != 2)
- return Error("Invalid GETRESULT record");
- unsigned OpNum = 0;
- Value *Op;
- getValueTypePair(Record, OpNum, NextValueNo, Op);
- unsigned Index = Record[1];
- I = ExtractValueInst::Create(Op, Index);
- InstructionList.push_back(I);
- break;
- }
-
case bitc::FUNC_CODE_INST_RET: // RET: [opty,opval<optional>]
{
unsigned Size = Record.size();
@@ -2134,33 +2347,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
unsigned OpNum = 0;
- SmallVector<Value *,4> Vs;
- do {
- Value *Op = NULL;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op))
- return Error("Invalid RET record");
- Vs.push_back(Op);
- } while(OpNum != Record.size());
-
- const Type *ReturnType = F->getReturnType();
- // Handle multiple return values. FIXME: Remove in LLVM 3.0.
- if (Vs.size() > 1 ||
- (ReturnType->isStructTy() &&
- (Vs.empty() || Vs[0]->getType() != ReturnType))) {
- Value *RV = UndefValue::get(ReturnType);
- for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
- I = InsertValueInst::Create(RV, Vs[i], i, "mrv");
- InstructionList.push_back(I);
- CurBB->getInstList().push_back(I);
- ValueList.AssignValue(I, NextValueNo++);
- RV = I;
- }
- I = ReturnInst::Create(Context, RV);
- InstructionList.push_back(I);
- break;
- }
+ Value *Op = NULL;
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+ return Error("Invalid RET record");
+ if (OpNum != Record.size())
+ return Error("Invalid RET record");
- I = ReturnInst::Create(Context, Vs[0]);
+ I = ReturnInst::Create(Context, Op);
InstructionList.push_back(I);
break;
}
@@ -2272,8 +2465,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
}
- I = InvokeInst::Create(Callee, NormalBB, UnwindBB,
- Ops.begin(), Ops.end());
+ I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops);
InstructionList.push_back(I);
cast<InvokeInst>(I)->setCallingConv(
static_cast<CallingConv::ID>(CCInfo));
@@ -2307,47 +2499,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break;
}
- case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
- // Autoupgrade malloc instruction to malloc call.
- // FIXME: Remove in LLVM 3.0.
- if (Record.size() < 3)
- return Error("Invalid MALLOC record");
- const PointerType *Ty =
- dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
- Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
- if (!Ty || !Size) return Error("Invalid MALLOC record");
- if (!CurBB) return Error("Invalid malloc instruction with no BB");
- const Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
- Constant *AllocSize = ConstantExpr::getSizeOf(Ty->getElementType());
- AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, Int32Ty);
- I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(),
- AllocSize, Size, NULL);
- InstructionList.push_back(I);
- break;
- }
- case bitc::FUNC_CODE_INST_FREE: { // FREE: [op, opty]
- unsigned OpNum = 0;
- Value *Op;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
- OpNum != Record.size())
- return Error("Invalid FREE record");
- if (!CurBB) return Error("Invalid free instruction with no BB");
- I = CallInst::CreateFree(Op, CurBB);
- InstructionList.push_back(I);
- break;
- }
case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
- // For backward compatibility, tolerate a lack of an opty, and use i32.
- // Remove this in LLVM 3.0.
- if (Record.size() < 3 || Record.size() > 4)
+ if (Record.size() != 4)
return Error("Invalid ALLOCA record");
- unsigned OpNum = 0;
const PointerType *Ty =
- dyn_cast_or_null<PointerType>(getTypeByID(Record[OpNum++]));
- const Type *OpTy = Record.size() == 4 ? getTypeByID(Record[OpNum++]) :
- Type::getInt32Ty(Context);
- Value *Size = getFnValueByID(Record[OpNum++], OpTy);
- unsigned Align = Record[OpNum++];
+ dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+ const Type *OpTy = getTypeByID(Record[1]);
+ Value *Size = getFnValueByID(Record[2], OpTy);
+ unsigned Align = Record[3];
if (!Ty || !Size) return Error("Invalid ALLOCA record");
I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
InstructionList.push_back(I);
@@ -2364,7 +2523,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_STORE2: { // STORE2:[ptrty, ptr, val, align, vol]
+ case bitc::FUNC_CODE_INST_STORE: { // STORE2:[ptrty, ptr, val, align, vol]
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
@@ -2377,24 +2536,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
- // FIXME: Legacy form of store instruction. Should be removed in LLVM 3.0.
- unsigned OpNum = 0;
- Value *Val, *Ptr;
- if (getValueTypePair(Record, OpNum, NextValueNo, Val) ||
- getValue(Record, OpNum,
- PointerType::getUnqual(Val->getType()), Ptr)||
- OpNum+2 != Record.size())
- return Error("Invalid STORE record");
-
- I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
- InstructionList.push_back(I);
- break;
- }
- // FIXME: Remove this in LLVM 3.0.
- case bitc::FUNC_CODE_INST_CALL:
- LLVM2_7MetadataDetected = true;
- case bitc::FUNC_CODE_INST_CALL2: {
+ case bitc::FUNC_CODE_INST_CALL: {
// CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...]
if (Record.size() < 3)
return Error("Invalid CALL record");
@@ -2416,7 +2558,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
SmallVector<Value*, 16> Args;
// Read the fixed params.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
- if (FTy->getParamType(i)->getTypeID()==Type::LabelTyID)
+ if (FTy->getParamType(i)->isLabelTy())
Args.push_back(getBasicBlock(Record[OpNum]));
else
Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
@@ -2436,7 +2578,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
}
- I = CallInst::Create(Callee, Args.begin(), Args.end());
+ I = CallInst::Create(Callee, Args);
InstructionList.push_back(I);
cast<CallInst>(I)->setCallingConv(
static_cast<CallingConv::ID>(CCInfo>>1));
@@ -2513,23 +2655,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
BlockAddrFwdRefs.erase(BAFRI);
}
- // FIXME: Remove this in LLVM 3.0.
- unsigned NewMDValueListSize = MDValueList.size();
-
// Trim the value list down to the size it was before we parsed this function.
ValueList.shrinkTo(ModuleValueListSize);
MDValueList.shrinkTo(ModuleMDValueListSize);
-
- // Backwards compatibility hack: Function-local metadata numbers
- // were previously not reset between functions. This is now fixed,
- // however we still need to understand the old numbering in order
- // to be able to read old bitcode files.
- // FIXME: Remove this in LLVM 3.0.
- if (LLVM2_7MetadataDetected)
- MDValueList.resize(NewMDValueListSize);
-
std::vector<BasicBlock*>().swap(FunctionBBs);
-
return false;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index f8fc079..1b3bf1a 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -44,9 +44,9 @@ class BitcodeReaderValueList {
/// number that holds the resolved value.
typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
ResolveConstantsTy ResolveConstants;
- LLVMContext& Context;
+ LLVMContext &Context;
public:
- BitcodeReaderValueList(LLVMContext& C) : Context(C) {}
+ BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
~BitcodeReaderValueList() {
assert(ResolveConstants.empty() && "Constants not resolved?");
}
@@ -131,7 +131,7 @@ class BitcodeReader : public GVMaterializer {
const char *ErrorString;
- std::vector<PATypeHolder> TypeList;
+ std::vector<Type*> TypeList;
BitcodeReaderValueList ValueList;
BitcodeReaderMDValueList MDValueList;
SmallVector<Instruction *, 64> InstructionList;
@@ -174,17 +174,10 @@ class BitcodeReader : public GVMaterializer {
typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
- /// LLVM2_7MetadataDetected - True if metadata produced by LLVM 2.7 or
- /// earlier was detected, in which case we behave slightly differently,
- /// for compatibility.
- /// FIXME: Remove in LLVM 3.0.
- bool LLVM2_7MetadataDetected;
-
public:
explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
: Context(C), TheModule(0), Buffer(buffer), BufferOwned(false),
- ErrorString(0), ValueList(C), MDValueList(C),
- LLVM2_7MetadataDetected(false) {
+ ErrorString(0), ValueList(C), MDValueList(C) {
HasReversedFunctionsWithBodies = false;
}
~BitcodeReader() {
@@ -217,12 +210,12 @@ public:
/// @returns true if an error occurred.
bool ParseTriple(std::string &Triple);
private:
- const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
+ Type *getTypeByID(unsigned ID);
+ Type *getTypeByIDOrNull(unsigned ID);
Value *getFnValueByID(unsigned ID, const Type *Ty) {
- if (Ty == Type::getMetadataTy(Context))
+ if (Ty && Ty->isMetadataTy())
return MDValueList.getValueFwdRef(ID);
- else
- return ValueList.getValueFwdRef(ID, Ty);
+ return ValueList.getValueFwdRef(ID, Ty);
}
BasicBlock *getBasicBlock(unsigned ID) const {
if (ID >= FunctionBBs.size()) return 0; // Invalid ID
@@ -266,7 +259,10 @@ private:
bool ParseModule();
bool ParseAttributeBlock();
bool ParseTypeTable();
- bool ParseTypeSymbolTable();
+ bool ParseOldTypeTable(); // FIXME: Remove in LLVM 3.1
+ bool ParseTypeTableBody();
+
+ bool ParseOldTypeSymbolTable(); // FIXME: Remove in LLVM 3.1
bool ParseValueSymbolTable();
bool ParseConstants();
bool RememberAndSkipFunctionBody();
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 6972a45..85d67ce 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -21,13 +21,14 @@
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Operator.h"
-#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
#include <cctype>
+#include <map>
using namespace llvm;
/// These are manifest constants used by the bitcode writer. They do not need to
@@ -100,13 +101,16 @@ static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
}
}
-static void WriteStringRecord(unsigned Code, const std::string &Str,
+static void WriteStringRecord(unsigned Code, StringRef Str,
unsigned AbbrevToUse, BitstreamWriter &Stream) {
SmallVector<unsigned, 64> Vals;
// Code: [strchar x N]
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
+ AbbrevToUse = 0;
Vals.push_back(Str[i]);
+ }
// Emit the finished record.
Stream.EmitRecord(Code, Vals, AbbrevToUse);
@@ -150,7 +154,7 @@ static void WriteAttributeTable(const ValueEnumerator &VE,
static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
const ValueEnumerator::TypeList &TypeList = VE.getTypes();
- Stream.EnterSubblock(bitc::TYPE_BLOCK_ID, 4 /*count from # abbrevs */);
+ Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
// Abbrev for TYPE_CODE_POINTER.
@@ -171,15 +175,32 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Log2_32_Ceil(VE.getTypes().size()+1)));
unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
- // Abbrev for TYPE_CODE_STRUCT.
+ // Abbrev for TYPE_CODE_STRUCT_ANON.
Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT));
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
Log2_32_Ceil(VE.getTypes().size()+1)));
- unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
+ unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
+
+ // Abbrev for TYPE_CODE_STRUCT_NAME.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+ unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
+ // Abbrev for TYPE_CODE_STRUCT_NAMED.
+ Abbv = new BitCodeAbbrev();
+ Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ Log2_32_Ceil(VE.getTypes().size()+1)));
+ unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
+
+
// Abbrev for TYPE_CODE_ARRAY.
Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
@@ -201,16 +222,15 @@ 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::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::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::OpaqueTyID: Code = bitc::TYPE_CODE_OPAQUE; 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;
@@ -241,13 +261,28 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
case Type::StructTyID: {
const StructType *ST = cast<StructType>(T);
// STRUCT: [ispacked, eltty x N]
- Code = bitc::TYPE_CODE_STRUCT;
TypeVals.push_back(ST->isPacked());
// Output all of the element types.
for (StructType::element_iterator I = ST->element_begin(),
E = ST->element_end(); I != E; ++I)
TypeVals.push_back(VE.getTypeID(*I));
- AbbrevToUse = StructAbbrev;
+
+ if (ST->isAnonymous()) {
+ Code = bitc::TYPE_CODE_STRUCT_ANON;
+ AbbrevToUse = StructAnonAbbrev;
+ } else {
+ if (ST->isOpaque()) {
+ Code = bitc::TYPE_CODE_OPAQUE;
+ } else {
+ Code = bitc::TYPE_CODE_STRUCT_NAMED;
+ AbbrevToUse = StructNamedAbbrev;
+ }
+
+ // Emit the name if it is present.
+ if (!ST->getName().empty())
+ WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(),
+ StructNameAbbrev, Stream);
+ }
break;
}
case Type::ArrayTyID: {
@@ -489,8 +524,8 @@ static void WriteMDNode(const MDNode *N,
Record.push_back(0);
}
}
- unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE2 :
- bitc::METADATA_NODE2;
+ unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE :
+ bitc::METADATA_NODE;
Stream.EmitRecord(MDCode, Record, 0);
Record.clear();
}
@@ -553,7 +588,7 @@ static void WriteModuleMetadata(const Module *M,
// Write named metadata operands.
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(NMD->getOperand(i)));
- Stream.EmitRecord(bitc::METADATA_NAMED_NODE2, Record, 0);
+ Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
Record.clear();
}
@@ -589,7 +624,7 @@ static void WriteMetadataAttachment(const Function &F,
SmallVector<uint64_t, 64> Record;
// Write metadata attachments
- // METADATA_ATTACHMENT2 - [m x [value, [n x [id, mdnode]]]
+ // 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)
@@ -607,7 +642,7 @@ static void WriteMetadataAttachment(const Function &F,
Record.push_back(MDs[i].first);
Record.push_back(VE.getValueID(MDs[i].second));
}
- Stream.EmitRecord(bitc::METADATA_ATTACHMENT2, Record, 0);
+ Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
}
@@ -1078,12 +1113,16 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
break;
- case Instruction::PHI:
+ case Instruction::PHI: {
+ const PHINode &PN = cast<PHINode>(I);
Code = bitc::FUNC_CODE_INST_PHI;
- Vals.push_back(VE.getTypeID(I.getType()));
- for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
- Vals.push_back(VE.getValueID(I.getOperand(i)));
+ Vals.push_back(VE.getTypeID(PN.getType()));
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+ Vals.push_back(VE.getValueID(PN.getIncomingValue(i)));
+ Vals.push_back(VE.getValueID(PN.getIncomingBlock(i)));
+ }
break;
+ }
case Instruction::Alloca:
Code = bitc::FUNC_CODE_INST_ALLOCA;
@@ -1102,7 +1141,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Vals.push_back(cast<LoadInst>(I).isVolatile());
break;
case Instruction::Store:
- Code = bitc::FUNC_CODE_INST_STORE2;
+ Code = bitc::FUNC_CODE_INST_STORE;
PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr
Vals.push_back(VE.getValueID(I.getOperand(0))); // val.
Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
@@ -1113,7 +1152,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
const PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
- Code = bitc::FUNC_CODE_INST_CALL2;
+ Code = bitc::FUNC_CODE_INST_CALL;
Vals.push_back(VE.getAttributeID(CI.getAttributes()));
Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()));
@@ -1257,7 +1296,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
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_LOC2, Vals);
+ Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
Vals.clear();
LastDL = DL;
@@ -1273,46 +1312,6 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
Stream.ExitBlock();
}
-/// WriteTypeSymbolTable - Emit a block for the specified type symtab.
-static void WriteTypeSymbolTable(const TypeSymbolTable &TST,
- const ValueEnumerator &VE,
- BitstreamWriter &Stream) {
- if (TST.empty()) return;
-
- Stream.EnterSubblock(bitc::TYPE_SYMTAB_BLOCK_ID, 3);
-
- // 7-bit fixed width VST_CODE_ENTRY strings.
- BitCodeAbbrev *Abbv = new BitCodeAbbrev();
- Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
- unsigned V7Abbrev = Stream.EmitAbbrev(Abbv);
-
- SmallVector<unsigned, 64> NameVals;
-
- for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
- TI != TE; ++TI) {
- // TST_ENTRY: [typeid, namechar x N]
- NameVals.push_back(VE.getTypeID(TI->second));
-
- const std::string &Str = TI->first;
- bool is7Bit = true;
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- NameVals.push_back((unsigned char)Str[i]);
- if (Str[i] & 128)
- is7Bit = false;
- }
-
- // Emit the finished record.
- Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0);
- NameVals.clear();
- }
-
- Stream.ExitBlock();
-}
-
// Emit blockinfo, which defines the standard abbreviations etc.
static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
// We only want to emit block info records for blocks that have multiple
@@ -1516,9 +1515,6 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// Emit metadata.
WriteModuleMetadataStore(M, Stream);
- // Emit the type symbol table information.
- WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream);
-
// Emit names for globals/functions etc.
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
@@ -1543,40 +1539,7 @@ enum {
DarwinBCHeaderSize = 5*4
};
-/// isARMTriplet - Return true if the triplet looks like:
-/// arm-*, thumb-*, armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*.
-static bool isARMTriplet(const std::string &TT) {
- size_t Pos = 0;
- size_t Size = TT.size();
- if (Size >= 6 &&
- TT[0] == 't' && TT[1] == 'h' && TT[2] == 'u' &&
- TT[3] == 'm' && TT[4] == 'b')
- Pos = 5;
- else if (Size >= 4 && TT[0] == 'a' && TT[1] == 'r' && TT[2] == 'm')
- Pos = 3;
- else
- return false;
-
- if (TT[Pos] == '-')
- return true;
- else if (TT[Pos] == 'v') {
- if (Size >= Pos+4 &&
- TT[Pos+1] == '6' && TT[Pos+2] == 't' && TT[Pos+3] == '2')
- return true;
- else if (Size >= Pos+4 &&
- TT[Pos+1] == '5' && TT[Pos+2] == 't' && TT[Pos+3] == 'e')
- return true;
- } else
- return false;
- while (++Pos < Size && TT[Pos] != '-') {
- if (!isdigit(TT[Pos]))
- return false;
- }
- return true;
-}
-
-static void EmitDarwinBCHeader(BitstreamWriter &Stream,
- const std::string &TT) {
+static void EmitDarwinBCHeader(BitstreamWriter &Stream, const Triple &TT) {
unsigned CPUType = ~0U;
// Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
@@ -1590,16 +1553,16 @@ static void EmitDarwinBCHeader(BitstreamWriter &Stream,
DARWIN_CPU_TYPE_POWERPC = 18
};
- if (TT.find("x86_64-") == 0)
+ Triple::ArchType Arch = TT.getArch();
+ if (Arch == Triple::x86_64)
CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
- else if (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
- TT[4] == '-' && TT[1] - '3' < 6)
+ else if (Arch == Triple::x86)
CPUType = DARWIN_CPU_TYPE_X86;
- else if (TT.find("powerpc-") == 0)
+ else if (Arch == Triple::ppc)
CPUType = DARWIN_CPU_TYPE_POWERPC;
- else if (TT.find("powerpc64-") == 0)
+ else if (Arch == Triple::ppc64)
CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
- else if (isARMTriplet(TT))
+ else if (Arch == Triple::arm || Arch == Triple::thumb)
CPUType = DARWIN_CPU_TYPE_ARM;
// Traditional Bitcode starts after header.
@@ -1645,11 +1608,9 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
void llvm::WriteBitcodeToStream(const Module *M, BitstreamWriter &Stream) {
// If this is darwin or another generic macho target, emit a file header and
// trailer if needed.
- bool isMacho =
- M->getTargetTriple().find("-darwin") != std::string::npos ||
- M->getTargetTriple().find("-macho") != std::string::npos;
- if (isMacho)
- EmitDarwinBCHeader(Stream, M->getTargetTriple());
+ Triple TT(M->getTargetTriple());
+ if (TT.isOSDarwin())
+ EmitDarwinBCHeader(Stream, TT);
// Emit the file header.
Stream.Emit((unsigned)'B', 8);
@@ -1662,6 +1623,6 @@ void llvm::WriteBitcodeToStream(const Module *M, BitstreamWriter &Stream) {
// Emit the module.
WriteModule(M, Stream);
- if (isMacho)
+ if (TT.isOSDarwin())
EmitDarwinBCTrailer(Stream, Stream.getBuffer().size());
}
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 5138c3c..b68bf92 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -17,7 +17,6 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Instructions.h"
#include <algorithm>
@@ -59,9 +58,6 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
I != E; ++I)
EnumerateValue(I->getAliasee());
- // Enumerate types used by the type symbol table.
- EnumerateTypeSymbolTable(M->getTypeSymbolTable());
-
// 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());
@@ -109,78 +105,12 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
// Optimize constant ordering.
OptimizeConstants(FirstConstant, Values.size());
-
- OptimizeTypes();
-
- // Now that we rearranged the type table, rebuild TypeMap.
- for (unsigned i = 0, e = Types.size(); i != e; ++i)
- TypeMap[Types[i]] = i+1;
-}
-
-struct TypeAndDeps {
- const Type *Ty;
- unsigned NumDeps;
-};
-
-static int CompareByDeps(const void *a, const void *b) {
- const TypeAndDeps &ta = *(const TypeAndDeps*) a;
- const TypeAndDeps &tb = *(const TypeAndDeps*) b;
- return ta.NumDeps - tb.NumDeps;
-}
-
-static void VisitType(const Type *Ty, SmallPtrSet<const Type*, 16> &Visited,
- std::vector<const Type*> &Out) {
- if (Visited.count(Ty))
- return;
-
- Visited.insert(Ty);
-
- for (Type::subtype_iterator I2 = Ty->subtype_begin(),
- E2 = Ty->subtype_end(); I2 != E2; ++I2) {
- const Type *InnerType = I2->get();
- VisitType(InnerType, Visited, Out);
- }
-
- Out.push_back(Ty);
}
-void ValueEnumerator::OptimizeTypes(void) {
- // If the types form a DAG, this will compute a topological sort and
- // no forward references will be needed when reading them in.
- // If there are cycles, this is a simple but reasonable heuristic for
- // the minimum feedback arc set problem.
- const unsigned NumTypes = Types.size();
- std::vector<TypeAndDeps> TypeDeps;
- TypeDeps.resize(NumTypes);
-
- for (unsigned I = 0; I < NumTypes; ++I) {
- const Type *Ty = Types[I];
- TypeDeps[I].Ty = Ty;
- TypeDeps[I].NumDeps = 0;
- }
-
- for (unsigned I = 0; I < NumTypes; ++I) {
- const Type *Ty = TypeDeps[I].Ty;
- for (Type::subtype_iterator I2 = Ty->subtype_begin(),
- E2 = Ty->subtype_end(); I2 != E2; ++I2) {
- const Type *InnerType = I2->get();
- unsigned InnerIndex = TypeMap.lookup(InnerType) - 1;
- TypeDeps[InnerIndex].NumDeps++;
- }
- }
- array_pod_sort(TypeDeps.begin(), TypeDeps.end(), CompareByDeps);
-
- SmallPtrSet<const Type*, 16> Visited;
- Types.clear();
- Types.reserve(NumTypes);
- for (unsigned I = 0; I < NumTypes; ++I) {
- VisitType(TypeDeps[I].Ty, Visited, Types);
- }
-}
unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
InstructionMapType::const_iterator I = InstructionMap.find(Inst);
- assert (I != InstructionMap.end() && "Instruction is not mapped!");
+ assert(I != InstructionMap.end() && "Instruction is not mapped!");
return I->second;
}
@@ -235,14 +165,6 @@ void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
}
-/// EnumerateTypeSymbolTable - Insert all of the types in the specified symbol
-/// table.
-void ValueEnumerator::EnumerateTypeSymbolTable(const TypeSymbolTable &TST) {
- for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
- TI != TE; ++TI)
- EnumerateType(TI->second);
-}
-
/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
/// table into the values table.
void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
@@ -394,20 +316,40 @@ void ValueEnumerator::EnumerateValue(const Value *V) {
void ValueEnumerator::EnumerateType(const Type *Ty) {
- unsigned &TypeID = TypeMap[Ty];
+ unsigned *TypeID = &TypeMap[Ty];
// We've already seen this type.
- if (TypeID)
+ if (*TypeID)
return;
- // First time we saw this type, add it.
- Types.push_back(Ty);
- TypeID = Types.size();
-
- // Enumerate subtypes.
+ // If it is a non-anonymous struct, mark the type as being visited so that we
+ // don't recursively visit it. This is safe because we allow forward
+ // references of these in the bitcode reader.
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isAnonymous())
+ *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.
+ //
+ // If this is actually a struct that we are treating as forward ref'able,
+ // 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();
}
// Enumerate the types for the specified value. If the value is a constant,
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index 1e42a26..6617b60 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -30,7 +30,6 @@ class Module;
class MDNode;
class NamedMDNode;
class AttrListPtr;
-class TypeSymbolTable;
class ValueSymbolTable;
class MDSymbolTable;
@@ -135,7 +134,6 @@ public:
private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
- void OptimizeTypes();
void EnumerateMDNodeOperands(const MDNode *N);
void EnumerateMetadata(const Value *MD);
@@ -146,7 +144,6 @@ private:
void EnumerateOperandType(const Value *V);
void EnumerateAttributes(const AttrListPtr &PAL);
- void EnumerateTypeSymbolTable(const TypeSymbolTable &ST);
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
void EnumerateNamedMetadata(const Module *M);
};
OpenPOWER on IntegriCloud