summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp14
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h5
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp152
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp16
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h5
5 files changed, 123 insertions, 69 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f18f7e6cf..8f8ab9d3ff 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -408,10 +408,10 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {
AliasInitWorklist.swap(AliasInits);
while (!GlobalInitWorklist.empty()) {
- unsigned ValID = GlobalInits.back().second;
+ unsigned ValID = GlobalInitWorklist.back().second;
if (ValID >= ValueList.size()) {
// Not ready to resolve this yet, it requires something later in the file.
- GlobalInitWorklist.push_back(GlobalInits.back());
+ GlobalInits.push_back(GlobalInitWorklist.back());
} else {
if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
GlobalInitWorklist.back().first->setInitializer(C);
@@ -826,7 +826,7 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
break;
}
// ALIAS: [alias type, aliasee val#, linkage]
- case bitc::MODULE_CODE_ALIAS:
+ case bitc::MODULE_CODE_ALIAS: {
if (Record.size() < 3)
return Error("Invalid MODULE_ALIAS record");
const Type *Ty = getTypeByID(Record[0]);
@@ -839,6 +839,14 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
AliasInits.push_back(std::make_pair(NewGA, Record[1]));
break;
}
+ /// MODULE_CODE_PURGEVALS: [numvals]
+ case bitc::MODULE_CODE_PURGEVALS:
+ // Trim down the value list to the specified size.
+ if (Record.size() < 1 || Record[0] > ValueList.size())
+ return Error("Invalid MODULE_PURGEVALS record");
+ ValueList.shrinkTo(Record[0]);
+ break;
+ }
Record.clear();
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 79bf8ea62f..8e21134602 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -41,6 +41,11 @@ public:
Value *back() const { return Uses.back(); }
void pop_back() { Uses.pop_back(); --NumOperands; }
bool empty() const { return NumOperands == 0; }
+ void shrinkTo(unsigned N) {
+ assert(N < NumOperands && "Invalid shrinkTo request!");
+ Uses.resize(N);
+ NumOperands = N;
+ }
virtual void print(std::ostream&) const {}
Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index b4f3f69b55..654eafea0c 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -324,69 +324,6 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
}
-/// 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);
-
- // FIXME: Set up the abbrev, we know how many types there are!
- // FIXME: We know if the type names can use 7-bit ascii.
-
- SmallVector<unsigned, 64> NameVals;
-
- for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
- TI != TE; ++TI) {
- unsigned AbbrevToUse = 0;
-
- // TST_ENTRY: [typeid, namelen, namechar x N]
- NameVals.push_back(VE.getTypeID(TI->second));
-
- const std::string &Str = TI->first;
- NameVals.push_back(Str.size());
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- NameVals.push_back(Str[i]);
-
- // Emit the finished record.
- Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
- NameVals.clear();
- }
-
- Stream.ExitBlock();
-}
-
-// Emit names for globals/functions etc.
-static void WriteValueSymbolTable(const ValueSymbolTable &VST,
- const ValueEnumerator &VE,
- BitstreamWriter &Stream) {
- if (VST.empty()) return;
- Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 3);
-
- // FIXME: Set up the abbrev, we know how many values there are!
- // FIXME: We know if the type names can use 7-bit ascii.
- SmallVector<unsigned, 64> NameVals;
-
- for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
- SI != SE; ++SI) {
- unsigned AbbrevToUse = 0;
-
- // VST_ENTRY: [valueid, namelen, namechar x N]
- NameVals.push_back(VE.getValueID(SI->getValue()));
-
- NameVals.push_back(SI->getKeyLength());
- for (const char *P = SI->getKeyData(),
- *E = SI->getKeyData()+SI->getKeyLength(); P != E; ++P)
- NameVals.push_back((unsigned char)*P);
-
- // Emit the finished record.
- Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
- NameVals.clear();
- }
- Stream.ExitBlock();
-}
-
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
const ValueEnumerator &VE,
BitstreamWriter &Stream) {
@@ -541,15 +478,85 @@ static void WriteModuleConstants(const ValueEnumerator &VE,
}
}
+
+static void WriteFunction(const Function &F, ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+
+}
+
+/// 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);
+
+ // FIXME: Set up the abbrev, we know how many types there are!
+ // FIXME: We know if the type names can use 7-bit ascii.
+
+ SmallVector<unsigned, 64> NameVals;
+
+ for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
+ TI != TE; ++TI) {
+ unsigned AbbrevToUse = 0;
+
+ // TST_ENTRY: [typeid, namelen, namechar x N]
+ NameVals.push_back(VE.getTypeID(TI->second));
+
+ const std::string &Str = TI->first;
+ NameVals.push_back(Str.size());
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ NameVals.push_back(Str[i]);
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
+ NameVals.clear();
+ }
+
+ Stream.ExitBlock();
+}
+
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ if (VST.empty()) return;
+ Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 3);
+
+ // FIXME: Set up the abbrev, we know how many values there are!
+ // FIXME: We know if the type names can use 7-bit ascii.
+ SmallVector<unsigned, 64> NameVals;
+
+ for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+ SI != SE; ++SI) {
+ unsigned AbbrevToUse = 0;
+
+ // VST_ENTRY: [valueid, namelen, namechar x N]
+ NameVals.push_back(VE.getValueID(SI->getValue()));
+
+ NameVals.push_back(SI->getKeyLength());
+ for (const char *P = SI->getKeyData(),
+ *E = SI->getKeyData()+SI->getKeyLength(); P != E; ++P)
+ NameVals.push_back((unsigned char)*P);
+
+ // Emit the finished record.
+ Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
+ NameVals.clear();
+ }
+ Stream.ExitBlock();
+}
+
+
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
// Emit the version number if it is non-zero.
if (CurVersion) {
- SmallVector<unsigned, 1> VersionVals;
- VersionVals.push_back(CurVersion);
- Stream.EmitRecord(bitc::MODULE_CODE_VERSION, VersionVals);
+ SmallVector<unsigned, 1> Vals;
+ Vals.push_back(CurVersion);
+ Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
}
// Analyze the module, enumerating globals, functions, etc.
@@ -565,6 +572,19 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) {
// Emit constants.
WriteModuleConstants(VE, Stream);
+ // FIXME: Purge aggregate values from the VE, emit a record that indicates how
+ // many to purge.
+ int NumNonAggregates = VE.PurgeAggregateValues();
+ if (NumNonAggregates != -1) {
+ SmallVector<unsigned, 1> Vals;
+ Vals.push_back(NumNonAggregates);
+ Stream.EmitRecord(bitc::MODULE_CODE_PURGEVALS, Vals);
+ }
+
+ // Emit function bodies.
+ for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
+ WriteFunction(*I, VE, Stream);
+
// Emit the type symbol table information.
WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream);
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index 1172c4fa21..c22dbf7d54 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -140,6 +140,22 @@ void ValueEnumerator::EnumerateType(const Type *Ty) {
EnumerateType(*I);
}
+/// PurgeAggregateValues - If there are any aggregate values at the end of the
+/// value list, remove them and return the count of the remaining values. If
+/// there are none, return -1.
+int ValueEnumerator::PurgeAggregateValues() {
+ // If there are no aggregate values at the end of the list, return -1.
+ if (Values.empty() || Values.back().first->getType()->isFirstClassType())
+ return -1;
+
+ // Otherwise, remove aggregate values...
+ while (!Values.empty() && !Values.back().first->getType()->isFirstClassType())
+ Values.pop_back();
+
+ // ... and return the new size.
+ return Values.size();
+}
+
#if 0
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index 31e6940d9f..83c2fb9d40 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -64,6 +64,11 @@ public:
const ValueList &getValues() const { return Values; }
const TypeList &getTypes() const { return Types; }
+ /// PurgeAggregateValues - If there are any aggregate values at the end of the
+ /// value list, remove them and return the count of the remaining values. If
+ /// there are none, return -1.
+ int PurgeAggregateValues();
+
/// incorporateFunction/purgeFunction - If you'd like to deal with a function,
/// use these two methods to get its data into the ValueEnumerator!
///