aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/LLVMBuild.txt4
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp331
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h5
-rw-r--r--lib/Bitcode/Reader/CMakeLists.txt5
-rw-r--r--lib/Bitcode/Reader/LLVMBuild.txt1
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp133
-rw-r--r--lib/Bitcode/Writer/CMakeLists.txt5
-rw-r--r--lib/Bitcode/Writer/LLVMBuild.txt1
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp40
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h4
10 files changed, 220 insertions, 309 deletions
diff --git a/lib/Bitcode/LLVMBuild.txt b/lib/Bitcode/LLVMBuild.txt
index 696440d..af9936b 100644
--- a/lib/Bitcode/LLVMBuild.txt
+++ b/lib/Bitcode/LLVMBuild.txt
@@ -15,8 +15,10 @@
;
;===------------------------------------------------------------------------===;
+[common]
+subdirectories = Reader Writer
+
[component_0]
type = Group
name = Bitcode
parent = Libraries
-
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 6ecdbae..d584015 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -403,14 +403,6 @@ Type *BitcodeReader::getTypeByID(unsigned ID) {
return TypeList[ID] = StructType::create(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
@@ -747,264 +739,6 @@ bool BitcodeReader::ParseTypeTableBody() {
}
}
-// 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::create(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::create(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_OLD: {
- // 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_FUNCTION: {
- // FUNCTION: [vararg, retty, paramty x N]
- if (Record.size() < 2)
- return Error("Invalid FUNCTION type record");
- std::vector<Type*> ArgTys;
- for (unsigned i = 2, e = Record.size(); i != e; ++i) {
- if (Type *Elt = getTypeByIDOrNull(Record[i]))
- ArgTys.push_back(Elt);
- else
- break;
- }
- if (ArgTys.size()+2 != Record.size())
- break; // Something was null.
- if ((ResultTy = getTypeByIDOrNull(Record[1])))
- 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::ParseOldTypeSymbolTable() {
- if (Stream.EnterSubBlock(bitc::TYPE_SYMTAB_BLOCK_ID_OLD))
- return Error("Malformed block record");
-
- SmallVector<uint64_t, 64> Record;
-
- // Read all the records for this type table.
- std::string TypeName;
- while (1) {
- unsigned Code = Stream.ReadCode();
- if (Code == bitc::END_BLOCK) {
- if (Stream.ReadBlockEnd())
- return Error("Error at end of type 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;
- }
-
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
- }
-
- // Read a record.
- Record.clear();
- switch (Stream.ReadRecord(Code, Record)) {
- default: // Default behavior: unknown type.
- break;
- case bitc::TST_CODE_ENTRY: // TST_ENTRY: [typeid, namechar x N]
- if (ConvertToString(Record, 1, TypeName))
- return Error("Invalid TST_ENTRY record");
- unsigned TypeID = Record[0];
- if (TypeID >= TypeList.size())
- return Error("Invalid Type ID in TST_ENTRY record");
-
- // Only apply the type name to a struct type with no name.
- if (StructType *STy = dyn_cast<StructType>(TypeList[TypeID]))
- if (!STy->isLiteral() && !STy->hasName())
- STy->setName(TypeName);
- TypeName.clear();
- break;
- }
- }
-}
-
bool BitcodeReader::ParseValueSymbolTable() {
if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
return Error("Malformed block record");
@@ -1553,6 +1287,50 @@ bool BitcodeReader::ParseConstants() {
return false;
}
+bool BitcodeReader::ParseUseLists() {
+ if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID))
+ 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");
+ 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 use list record.
+ Record.clear();
+ switch (Stream.ReadRecord(Code, Record)) {
+ default: // Default behavior: unknown type.
+ break;
+ case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD.
+ unsigned RecordLength = Record.size();
+ if (RecordLength < 1)
+ return Error ("Invalid UseList reader!");
+ UseListRecords.push_back(Record);
+ break;
+ }
+ }
+ }
+}
+
/// RememberAndSkipFunctionBody - When we see the block for a function body,
/// remember where it is and then skip it. This lets us lazily deserialize the
/// functions.
@@ -1636,14 +1414,6 @@ bool BitcodeReader::ParseModule() {
if (ParseTypeTable())
return true;
break;
- 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:
if (ParseValueSymbolTable())
return true;
@@ -1667,6 +1437,10 @@ bool BitcodeReader::ParseModule() {
if (RememberAndSkipFunctionBody())
return true;
break;
+ case bitc::USELIST_BLOCK_ID:
+ if (ParseUseLists())
+ return true;
+ break;
}
continue;
}
@@ -2975,12 +2749,6 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
}
std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics);
- // Upgrade to new EH scheme. N.B. This will go away in 3.1.
- UpgradeExceptionHandling(M);
-
- // Check debug info intrinsics.
- CheckDebugInfoIntrinsics(TheModule);
-
return false;
}
@@ -3026,6 +2794,9 @@ Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
return 0;
}
+ // TODO: Restore the use-lists to the in-memory state when the bitcode was
+ // written. We must defer until the Module has been fully materialized.
+
return M;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 6e6118c..978b15b 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -135,6 +135,7 @@ class BitcodeReader : public GVMaterializer {
BitcodeReaderValueList ValueList;
BitcodeReaderMDValueList MDValueList;
SmallVector<Instruction *, 64> InstructionList;
+ SmallVector<SmallVector<uint64_t, 64>, 64> UseListRecords;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
@@ -211,7 +212,6 @@ public:
bool ParseTriple(std::string &Triple);
private:
Type *getTypeByID(unsigned ID);
- Type *getTypeByIDOrNull(unsigned ID);
Value *getFnValueByID(unsigned ID, Type *Ty) {
if (Ty && Ty->isMetadataTy())
return MDValueList.getValueFwdRef(ID);
@@ -259,10 +259,8 @@ private:
bool ParseModule();
bool ParseAttributeBlock();
bool ParseTypeTable();
- bool ParseOldTypeTable(); // FIXME: Remove in LLVM 3.1
bool ParseTypeTableBody();
- bool ParseOldTypeSymbolTable(); // FIXME: Remove in LLVM 3.1
bool ParseValueSymbolTable();
bool ParseConstants();
bool RememberAndSkipFunctionBody();
@@ -271,6 +269,7 @@ private:
bool ParseMetadata();
bool ParseMetadataAttachment();
bool ParseModuleTriple(std::string &Triple);
+ bool ParseUseLists();
};
} // End llvm namespace
diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt
index 37bebc4..693d431 100644
--- a/lib/Bitcode/Reader/CMakeLists.txt
+++ b/lib/Bitcode/Reader/CMakeLists.txt
@@ -2,8 +2,3 @@ add_llvm_library(LLVMBitReader
BitReader.cpp
BitcodeReader.cpp
)
-
-add_llvm_library_dependencies(LLVMBitReader
- LLVMCore
- LLVMSupport
- )
diff --git a/lib/Bitcode/Reader/LLVMBuild.txt b/lib/Bitcode/Reader/LLVMBuild.txt
index 948b335..c85a87b 100644
--- a/lib/Bitcode/Reader/LLVMBuild.txt
+++ b/lib/Bitcode/Reader/LLVMBuild.txt
@@ -20,4 +20,3 @@ type = Library
name = BitReader
parent = Bitcode
required_libraries = Core Support
-
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index e758f94..d980163 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -23,6 +23,7 @@
#include "llvm/Operator.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -31,6 +32,12 @@
#include <map>
using namespace llvm;
+static cl::opt<bool>
+EnablePreserveUseListOrdering("enable-bc-uselist-preserve",
+ cl::desc("Turn on experimental support for "
+ "use-list order preservation."),
+ cl::init(false), cl::Hidden);
+
/// These are manifest constants used by the bitcode writer. They do not need to
/// be kept in sync with the reader, but need to be consistent within this file.
enum {
@@ -194,11 +201,12 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
SmallVector<uint64_t, 64> TypeVals;
+ uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
// Abbrev for TYPE_CODE_POINTER.
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0
unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
@@ -207,8 +215,8 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_STRUCT_ANON.
@@ -216,8 +224,8 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
// Abbrev for TYPE_CODE_STRUCT_NAME.
@@ -232,16 +240,16 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
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)));
+ 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));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size
- Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- Log2_32_Ceil(VE.getTypes().size()+1)));
+ Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
// Emit an entry count so the reader can reserve space.
@@ -497,8 +505,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
// Emit the function proto information.
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
- // FUNCTION: [type, callingconv, isproto, paramattr,
- // linkage, alignment, section, visibility, gc, unnamed_addr]
+ // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
+ // section, visibility, gc, unnamed_addr]
Vals.push_back(VE.getTypeID(F->getType()));
Vals.push_back(F->getCallingConv());
Vals.push_back(F->isDeclaration());
@@ -518,6 +526,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
// Emit the alias information.
for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end();
AI != E; ++AI) {
+ // ALIAS: [alias type, aliasee val#, linkage, visibility]
Vals.push_back(VE.getTypeID(AI->getType()));
Vals.push_back(VE.getValueID(AI->getAliasee()));
Vals.push_back(getEncodedLinkage(AI));
@@ -1571,6 +1580,102 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
Stream.ExitBlock();
}
+// 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.
+ return true;
+}
+
+static void WriteUseList(const Value *V, const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+
+ // One or zero uses can't get out of order.
+ if (V->use_empty() || V->hasNUses(1))
+ return;
+
+ // Make a copy of the in-memory use-list for sorting.
+ unsigned UseListSize = std::distance(V->use_begin(), V->use_end());
+ SmallVector<const User*, 8> UseList;
+ UseList.reserve(UseListSize);
+ for (Value::const_use_iterator I = V->use_begin(), E = V->use_end();
+ I != E; ++I) {
+ const User *U = *I;
+ UseList.push_back(U);
+ }
+
+ // Sort the copy based on the order read by the BitcodeReader.
+ std::sort(UseList.begin(), UseList.end(), bitcodereader_order);
+
+ // TODO: Generate a diff between the BitcodeWriter in-memory use-list and the
+ // sorted list (i.e., the expected BitcodeReader in-memory use-list).
+
+ // TODO: Emit the USELIST_CODE_ENTRYs.
+}
+
+static void WriteFunctionUseList(const Function *F, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ VE.incorporateFunction(*F);
+
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI)
+ WriteUseList(AI, VE, Stream);
+ for (Function::const_iterator BB = F->begin(), FE = F->end(); BB != FE;
+ ++BB) {
+ WriteUseList(BB, VE, Stream);
+ for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE;
+ ++II) {
+ WriteUseList(II, VE, Stream);
+ for (User::const_op_iterator OI = II->op_begin(), E = II->op_end();
+ OI != E; ++OI) {
+ if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+ isa<InlineAsm>(*OI))
+ WriteUseList(*OI, VE, Stream);
+ }
+ }
+ }
+ VE.purgeFunction();
+}
+
+// Emit use-lists.
+static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
+
+ // XXX: this modifies the module, but in a way that should never change the
+ // behavior of any pass or codegen in LLVM. The problem is that GVs may
+ // contain entries in the use_list that do not exist in the Module and are
+ // not stored in the .bc file.
+ 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(),
+ GE = M->global_end(); GI != GE; ++GI) {
+ WriteUseList(GI, VE, Stream);
+
+ // Write the global variable initializers.
+ if (GI->hasInitializer())
+ WriteUseList(GI->getInitializer(), VE, Stream);
+ }
+
+ // Write the functions.
+ for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
+ WriteUseList(FI, VE, Stream);
+ if (!FI->isDeclaration())
+ WriteFunctionUseList(FI, VE, Stream);
+ }
+
+ // Write the aliases.
+ for (Module::const_alias_iterator AI = M->alias_begin(), AE = M->alias_end();
+ AI != AE; ++AI) {
+ WriteUseList(AI, VE, Stream);
+ WriteUseList(AI->getAliasee(), VE, Stream);
+ }
+
+ Stream.ExitBlock();
+}
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
@@ -1616,6 +1721,10 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// Emit names for globals/functions etc.
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
+ // Emit use-lists.
+ if (EnablePreserveUseListOrdering)
+ WriteModuleUseLists(M, VE, Stream);
+
Stream.ExitBlock();
}
diff --git a/lib/Bitcode/Writer/CMakeLists.txt b/lib/Bitcode/Writer/CMakeLists.txt
index 3cf9056..f097b09 100644
--- a/lib/Bitcode/Writer/CMakeLists.txt
+++ b/lib/Bitcode/Writer/CMakeLists.txt
@@ -4,8 +4,3 @@ add_llvm_library(LLVMBitWriter
BitcodeWriterPass.cpp
ValueEnumerator.cpp
)
-
-add_llvm_library_dependencies(LLVMBitWriter
- LLVMCore
- LLVMSupport
- )
diff --git a/lib/Bitcode/Writer/LLVMBuild.txt b/lib/Bitcode/Writer/LLVMBuild.txt
index 39ff04e..7d9e1de 100644
--- a/lib/Bitcode/Writer/LLVMBuild.txt
+++ b/lib/Bitcode/Writer/LLVMBuild.txt
@@ -20,4 +20,3 @@ type = Library
name = BitWriter
parent = Bitcode
required_libraries = Core Support
-
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 9ae9905..1c4d670 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -19,6 +19,8 @@
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Instructions.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
@@ -107,7 +109,6 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
OptimizeConstants(FirstConstant, Values.size());
}
-
unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
InstructionMapType::const_iterator I = InstructionMap.find(Inst);
assert(I != InstructionMap.end() && "Instruction is not mapped!");
@@ -130,6 +131,43 @@ unsigned ValueEnumerator::getValueID(const Value *V) const {
return I->second-1;
}
+void ValueEnumerator::dump() const {
+ print(dbgs(), ValueMap, "Default");
+ dbgs() << '\n';
+ print(dbgs(), MDValueMap, "MetaData");
+ dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+ const char *Name) const {
+
+ OS << "Map Name: " << Name << "\n";
+ OS << "Size: " << Map.size() << "\n";
+ for (ValueMapType::const_iterator I = Map.begin(),
+ E = Map.end(); I != E; ++I) {
+
+ const Value *V = I->first;
+ if (V->hasName())
+ OS << "Value: " << V->getName();
+ else
+ OS << "Value: [null]\n";
+ V->dump();
+
+ OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+ for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
+ UI != UE; ++UI) {
+ if (UI != V->use_begin())
+ OS << ",";
+ if((*UI)->hasName())
+ OS << " " << (*UI)->getName();
+ else
+ OS << " [null]";
+
+ }
+ OS << "\n\n";
+ }
+}
+
// Optimize constant ordering.
namespace {
struct CstSortPredicate {
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index b6fc920..a6ca536 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -32,6 +32,7 @@ class NamedMDNode;
class AttrListPtr;
class ValueSymbolTable;
class MDSymbolTable;
+class raw_ostream;
class ValueEnumerator {
public:
@@ -83,6 +84,9 @@ private:
public:
ValueEnumerator(const Module *M);
+ void dump() const;
+ void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+
unsigned getValueID(const Value *V) const;
unsigned getTypeID(Type *T) const {