[llvm-commits] CVS: llvm/lib/Bitcode/Writer/ValueEnumerator.cpp ValueEnumerator.h Writer.cpp
Chris Lattner
sabre at nondot.org
Mon Apr 23 17:16:22 PDT 2007
Changes in directory llvm/lib/Bitcode/Writer:
ValueEnumerator.cpp updated: 1.1 -> 1.2
ValueEnumerator.h updated: 1.2 -> 1.3
Writer.cpp updated: 1.5 -> 1.6
---
Log message:
Emit module-level constants.
---
Diffs of the changes: (+118 -10)
ValueEnumerator.cpp | 5 +-
ValueEnumerator.h | 8 +--
Writer.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 118 insertions(+), 10 deletions(-)
Index: llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
diff -u llvm/lib/Bitcode/Writer/ValueEnumerator.cpp:1.1 llvm/lib/Bitcode/Writer/ValueEnumerator.cpp:1.2
--- llvm/lib/Bitcode/Writer/ValueEnumerator.cpp:1.1 Sun Apr 22 01:24:45 2007
+++ llvm/lib/Bitcode/Writer/ValueEnumerator.cpp Mon Apr 23 19:16:04 2007
@@ -56,9 +56,12 @@
// FIXME: std::partition the type and value tables so that first-class types
- // come earlier than aggregates.
+ // come earlier than aggregates. FIXME: Emit a marker into the module
+ // indicating which aggregates types AND values can be dropped form the table.
// FIXME: Sort type/value tables by frequency.
+
+ // FIXME: Sort constants by type to reduce size.
}
/// EnumerateTypeSymbolTable - Insert all of the types in the specified symbol
Index: llvm/lib/Bitcode/Writer/ValueEnumerator.h
diff -u llvm/lib/Bitcode/Writer/ValueEnumerator.h:1.2 llvm/lib/Bitcode/Writer/ValueEnumerator.h:1.3
--- llvm/lib/Bitcode/Writer/ValueEnumerator.h:1.2 Mon Apr 23 16:23:41 2007
+++ llvm/lib/Bitcode/Writer/ValueEnumerator.h Mon Apr 23 19:16:04 2007
@@ -35,15 +35,13 @@
// For each value, we remember its Value* and occurrence frequency.
typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
private:
- TypeList Types;
-
typedef DenseMap<const Type*, unsigned> TypeMapType;
TypeMapType TypeMap;
+ TypeList Types;
- ValueList Values;
-
typedef DenseMap<const Value*, unsigned> ValueMapType;
ValueMapType ValueMap;
+ ValueList Values;
ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT
@@ -63,7 +61,7 @@
return I->second-1;
}
-
+ const ValueList &getValues() const { return Values; }
const TypeList &getTypes() const { return Types; }
/// incorporateFunction/purgeFunction - If you'd like to deal with a function,
Index: llvm/lib/Bitcode/Writer/Writer.cpp
diff -u llvm/lib/Bitcode/Writer/Writer.cpp:1.5 llvm/lib/Bitcode/Writer/Writer.cpp:1.6
--- llvm/lib/Bitcode/Writer/Writer.cpp:1.5 Mon Apr 23 15:35:01 2007
+++ llvm/lib/Bitcode/Writer/Writer.cpp Mon Apr 23 19:16:04 2007
@@ -15,6 +15,7 @@
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "ValueEnumerator.h"
+#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h"
@@ -296,7 +297,7 @@
NameVals.push_back(Str[i]);
// Emit the finished record.
- Stream.EmitRecord(bitc::TST_ENTRY_CODE, NameVals, AbbrevToUse);
+ Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
NameVals.clear();
}
@@ -327,13 +328,118 @@
NameVals.push_back((unsigned char)*P);
// Emit the finished record.
- Stream.EmitRecord(bitc::VST_ENTRY_CODE, NameVals, AbbrevToUse);
+ Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, AbbrevToUse);
NameVals.clear();
}
Stream.ExitBlock();
}
+static void WriteConstants(unsigned FirstVal, unsigned LastVal,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ if (FirstVal == LastVal) return;
+
+ Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 2);
+
+ // FIXME: Install and use abbrevs to reduce size.
+
+ SmallVector<uint64_t, 64> Record;
+
+ const ValueEnumerator::ValueList &Vals = VE.getValues();
+ const Type *LastTy = 0;
+ for (unsigned i = FirstVal; i != LastVal; ++i) {
+ const Value *V = Vals[i].first;
+ // If we need to switch types, do so now.
+ if (V->getType() != LastTy) {
+ LastTy = V->getType();
+ Record.push_back(VE.getTypeID(LastTy));
+ Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record);
+ Record.clear();
+ }
+
+ if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+ assert(0 && IA && "FIXME: Inline asm writing unimp!");
+ continue;
+ }
+ const Constant *C = cast<Constant>(V);
+ unsigned Code = -1U;
+ unsigned AbbrevToUse = 0;
+ if (C->isNullValue()) {
+ Code = bitc::CST_CODE_NULL;
+ } else if (isa<UndefValue>(C)) {
+ Code = bitc::CST_CODE_UNDEF;
+ } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
+ if (IV->getBitWidth() <= 64) {
+ int64_t V = IV->getSExtValue();
+ if (V >= 0)
+ Record.push_back(V << 1);
+ else
+ Record.push_back((-V << 1) | 1);
+ Code = bitc::CST_CODE_INTEGER;
+ } else { // Wide integers, > 64 bits in size.
+ // We have an arbitrary precision integer value to write whose
+ // bit width is > 64. However, in canonical unsigned integer
+ // format it is likely that the high bits are going to be zero.
+ // So, we only write the number of active words.
+ unsigned NWords = IV->getValue().getActiveWords();
+ const uint64_t *RawWords = IV->getValue().getRawData();
+ Record.push_back(NWords);
+ for (unsigned i = 0; i != NWords; ++i) {
+ int64_t V = RawWords[i];
+ if (V >= 0)
+ Record.push_back(V << 1);
+ else
+ Record.push_back((-V << 1) | 1);
+ }
+ Code = bitc::CST_CODE_WIDE_INTEGER;
+ }
+ } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+ Code = bitc::CST_CODE_FLOAT;
+ if (CFP->getType() == Type::FloatTy) {
+ Record.push_back(FloatToBits((float)CFP->getValue()));
+ } else {
+ assert (CFP->getType() == Type::DoubleTy && "Unknown FP type!");
+ Record.push_back(DoubleToBits((double)CFP->getValue()));
+ }
+ } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
+ isa<ConstantVector>(V)) {
+ Code = bitc::CST_CODE_AGGREGATE;
+ Record.push_back(C->getNumOperands());
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+ Record.push_back(VE.getValueID(C->getOperand(i)));
+ } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ Code = bitc::CST_CODE_CONSTEXPR;
+ // FIXME: optimize for binops, compares, etc.
+ Record.push_back(CE->getOpcode());
+ Record.push_back(CE->getNumOperands());
+ for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
+ Record.push_back(VE.getValueID(C->getOperand(i)));
+ // Compares also pass their predicate.
+ if (CE->isCompare())
+ Record.push_back((unsigned)CE->getPredicate());
+ } else {
+ assert(0 && "Unknown constant!");
+ }
+ Stream.EmitRecord(Code, Record, AbbrevToUse);
+ Record.clear();
+ }
+ Stream.ExitBlock();
+}
+
+static void WriteModuleConstants(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const ValueEnumerator::ValueList &Vals = VE.getValues();
+
+ // Find the first constant to emit, which is the first non-globalvalue value.
+ // We know globalvalues have been emitted by WriteModuleInfo.
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (!isa<GlobalValue>(Vals[i].first)) {
+ WriteConstants(i, Vals.size(), VE, Stream);
+ return;
+ }
+ }
+}
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream) {
@@ -352,12 +458,13 @@
// Emit information describing all of the types in the module.
WriteTypeTable(VE, Stream);
- // FIXME: Emit constants.
-
// Emit top-level description of module, including target triple, inline asm,
// descriptors for global variables, and function prototype info.
WriteModuleInfo(M, VE, Stream);
+ // Emit constants.
+ WriteModuleConstants(VE, Stream);
+
// Emit the type symbol table information.
WriteTypeSymbolTable(M->getTypeSymbolTable(), VE, Stream);
More information about the llvm-commits
mailing list