diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Bytecode/Writer/ConstantWriter.cpp | 53 | ||||
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 20 | ||||
-rw-r--r-- | lib/Bytecode/Writer/WriterInternals.h | 11 |
3 files changed, 63 insertions, 21 deletions
diff --git a/lib/Bytecode/Writer/ConstantWriter.cpp b/lib/Bytecode/Writer/ConstantWriter.cpp index 12043b0..02569ec 100644 --- a/lib/Bytecode/Writer/ConstantWriter.cpp +++ b/lib/Bytecode/Writer/ConstantWriter.cpp @@ -26,6 +26,12 @@ ConstantBytes("bytecodewriter", "Bytes of constants"); static Statistic<> NumConstants("bytecodewriter", "Number of constants"); +static Statistic<> +NumStrConstants("bytecodewriter", "Number of string constants"); +static Statistic<> +NumStrBytes("bytecodewriter", "Number of string constant bytes"); + + void BytecodeWriter::outputType(const Type *T) { TypeBytes -= Out.size(); output_vbr((unsigned)T->getPrimitiveID(), Out); @@ -109,7 +115,7 @@ void BytecodeWriter::outputType(const Type *T) { TypeBytes += Out.size(); } -bool BytecodeWriter::outputConstant(const Constant *CPV) { +void BytecodeWriter::outputConstant(const Constant *CPV) { ConstantBytes -= Out.size(); assert((CPV->getType()->isPrimitiveType() || !CPV->isNullValue()) && "Shouldn't output null constants!"); @@ -133,7 +139,7 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) { output_vbr((unsigned)Slot, Out); } ConstantBytes += Out.size(); - return false; + return; } else { output_vbr(0U, Out); // flag as not a ConstantExpr } @@ -166,10 +172,9 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) { case Type::ArrayTyID: { const ConstantArray *CPA = cast<ConstantArray>(CPV); - unsigned size = CPA->getValues().size(); - assert(size == cast<ArrayType>(CPA->getType())->getNumElements() - && "ConstantArray out of whack!"); - for (unsigned i = 0; i < size; i++) { + assert(!CPA->isString() && "Constant strings should be handled specially!"); + + for (unsigned i = 0; i != CPA->getNumOperands(); ++i) { int Slot = Table.getSlot(CPA->getOperand(i)); assert(Slot != -1 && "Constant used but not available!!"); output_vbr((unsigned)Slot, Out); @@ -215,6 +220,38 @@ bool BytecodeWriter::outputConstant(const Constant *CPV) { << " type '" << CPV->getType()->getName() << "'\n"; break; } - ConstantBytes += Out.size(); - return false; + ConstantBytes += Out.size(); + return; +} + +void BytecodeWriter::outputConstantStrings() { + SlotCalculator::string_iterator I = Table.string_begin(); + SlotCalculator::string_iterator E = Table.string_end(); + if (I == E) return; // No strings to emit + + // If we have != 0 strings to emit, output them now. Strings are emitted into + // the 'void' type plane. + output_vbr(unsigned(E-I), Out); + output_vbr(Type::VoidTyID, Out); + + ConstantBytes -= Out.size(); + NumStrBytes -= Out.size();; + + // Emit all of the strings. + for (I = Table.string_begin(); I != E; ++I) { + const ConstantArray *Str = *I; + int Slot = Table.getSlot(Str->getType()); + assert(Slot != -1 && "Constant string of unknown type?"); + output_vbr((unsigned)Slot, Out); + + // Now that we emitted the type (which indicates the size of the string), + // emit all of the characters. + std::string Val = Str->getAsString(); + output_data(Val.c_str(), Val.c_str()+Val.size(), Out); + + ++NumConstants; + ++NumStrConstants; + } + ConstantBytes += Out.size(); + NumStrBytes += Out.size();; } diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index ca50b5a..2020a3a 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -24,9 +24,10 @@ #include "WriterInternals.h" #include "llvm/Bytecode/WriteBytecodePass.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" -#include "llvm/DerivedTypes.h" #include "Support/STLExtras.h" #include "Support/Statistic.h" #include "Support/Debug.h" @@ -54,7 +55,9 @@ ModuleInfoBytes("bytecodewriter", "Bytes of module info"); BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M) : Out(o), Table(M, true) { - outputSignature(); + // Emit the signature... + static const unsigned char *Sig = (const unsigned char*)"llvm"; + output_data(Sig, Sig+4, Out); // Emit the top level CLASS block. BytecodeBlock ModuleBlock(BytecodeFormat::Module, Out); @@ -111,9 +114,12 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*> &Plane, unsigned StartNo) { unsigned ValNo = StartNo; - // Scan through and ignore function arguments/global values... - for (; ValNo < Plane.size() && (isa<Argument>(Plane[ValNo]) || - isa<GlobalValue>(Plane[ValNo])); ValNo++) + // Scan through and ignore function arguments, global values, and constant + // strings. + for (; ValNo < Plane.size() && + (isa<Argument>(Plane[ValNo]) || isa<GlobalValue>(Plane[ValNo]) || + (isa<ConstantArray>(Plane[ValNo]) && + cast<ConstantArray>(Plane[ValNo])->isString())); ValNo++) /*empty*/; unsigned NC = ValNo; // Number of constants @@ -171,6 +177,10 @@ void BytecodeWriter::outputConstants(bool isFunction) { } } + // Output module-level string constants before any other constants.x + if (!isFunction) + outputConstantStrings(); + for (unsigned pno = 0; pno != NumPlanes; pno++) if (pno != Type::TypeTyID) { // Type plane handled above. const std::vector<const Value*> &Plane = Table.getPlane(pno); diff --git a/lib/Bytecode/Writer/WriterInternals.h b/lib/Bytecode/Writer/WriterInternals.h index 9fb778d..51ec362 100644 --- a/lib/Bytecode/Writer/WriterInternals.h +++ b/lib/Bytecode/Writer/WriterInternals.h @@ -33,22 +33,17 @@ class BytecodeWriter { public: BytecodeWriter(std::deque<unsigned char> &o, const Module *M); -protected: +private: void outputConstants(bool isFunction); + void outputConstantStrings(); void outputFunction(const Function *F); void processInstruction(const Instruction &I); -private : - inline void outputSignature() { - static const unsigned char *Sig = (const unsigned char*)"llvm"; - Out.insert(Out.end(), Sig, Sig+4); // output the bytecode signature... - } - void outputModuleInfoBlock(const Module *C); void outputSymbolTable(const SymbolTable &ST); void outputConstantsInPlane(const std::vector<const Value*> &Plane, unsigned StartNo); - bool outputConstant(const Constant *CPV); + void outputConstant(const Constant *CPV); void outputType(const Type *T); }; |