From e6e364c1986e54076fab080ec2f8cec1da8b7f7b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 26 Apr 2007 05:53:54 +0000 Subject: [PATCH] start code for writing out instructions. Separate BB#s from normal value #'s. llvm-svn: 36472 --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 67 ++++++++++++++++++++- llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 10 ++- llvm/lib/Bitcode/Writer/ValueEnumerator.h | 11 +++- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 152339502f73..421316cb3bb1 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -17,6 +17,7 @@ #include "ValueEnumerator.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ValueSymbolTable.h" @@ -331,7 +332,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 2); - // FIXME: Install and use abbrevs to reduce size. + // FIXME: Install and use abbrevs to reduce size. Install them globally so + // they don't need to be reemitted for each function body. SmallVector Record; @@ -478,12 +480,75 @@ static void WriteModuleConstants(const ValueEnumerator &VE, } } +/// WriteInstruction - Emit an instruction to the specified stream. +static void WriteInstruction(const Instruction &I, ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVector &Vals) { + return; // FIXME: REMOVE + + + unsigned Code = 0; + unsigned AbbrevToUse = 0; + switch (I.getOpcode()) { + default: + if (Instruction::isCast(I.getOpcode())) { + Code = bitc::FUNC_CODE_INST_BINOP; + Vals.push_back(GetEncodedCastOpcode(I.getOpcode())); + Vals.push_back(VE.getTypeID(I.getType())); + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); + Vals.push_back(VE.getValueID(I.getOperand(0))); + } else { + assert(isa(I) && "Unknown instruction!"); + Code = bitc::CST_CODE_CE_BINOP; + Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode())); + Vals.push_back(VE.getTypeID(I.getType())); + Vals.push_back(VE.getValueID(I.getOperand(0))); + Vals.push_back(VE.getValueID(I.getOperand(1))); + } + break; + + + case Instruction::Unwind: + Code = bitc::FUNC_CODE_INST_UNWIND; + break; + case Instruction::Unreachable: + Code = bitc::FUNC_CODE_INST_UNREACHABLE; + break; + + } + + Stream.EmitRecord(Code, Vals, AbbrevToUse); + Vals.clear(); +} + /// WriteFunction - Emit a function body to the module stream. static void WriteFunction(const Function &F, ValueEnumerator &VE, BitstreamWriter &Stream) { + Stream.EnterSubblock(bitc::TYPE_SYMTAB_BLOCK_ID, 3); VE.incorporateFunction(F); + + SmallVector Vals; + + // Emit the number of basic blocks, so the reader can create them ahead of + // time. + Vals.push_back(VE.getBasicBlocks().size()); + Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); + Vals.clear(); + + // FIXME: Function attributes? + + // If there are function-local constants, emit them now. + unsigned CstStart, CstEnd; + VE.getFunctionConstantRange(CstStart, CstEnd); + WriteConstants(CstStart, CstEnd, VE, Stream); + + // Finally, emit all the instructions, in order. + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) + WriteInstruction(*I, VE, Stream, Vals); VE.purgeFunction(); + Stream.ExitBlock(); } /// WriteTypeSymbolTable - Emit a block for the specified type symtab. diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 830ac612fb56..fab1d9c684db 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -162,13 +162,15 @@ int ValueEnumerator::PurgeAggregateValues() { } void ValueEnumerator::incorporateFunction(const Function &F) { - ModuleLevel = Values.size(); + NumModuleValues = Values.size(); // Adding function arguments to the value table. for(Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) EnumerateValue(I); + FirstFuncConstantID = Values.size(); + // Add all function-level constants to the value table. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) @@ -182,6 +184,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) { BasicBlocks.push_back(BB); } + FirstInstID = Values.size(); + // Add all of the instructions. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { @@ -193,12 +197,12 @@ void ValueEnumerator::incorporateFunction(const Function &F) { void ValueEnumerator::purgeFunction() { /// Remove purged values from the ValueMap. - for (unsigned i = ModuleLevel, e = Values.size(); i != e; ++i) + for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) ValueMap.erase(Values[i].first); for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) ValueMap.erase(BasicBlocks[i]); - Values.resize(ModuleLevel); + Values.resize(NumModuleValues); BasicBlocks.clear(); } diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index d9839c6c83e6..77f27dad68bc 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -49,7 +49,9 @@ private: /// When a function is incorporated, this is the size of the Values list /// before incorporation. - unsigned ModuleLevel; + unsigned NumModuleValues; + unsigned FirstFuncConstantID; + unsigned FirstInstID; ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT @@ -68,6 +70,13 @@ public: return I->second-1; } + /// getFunctionConstantRange - Return the range of values that corresponds to + /// function-local constants. + void getFunctionConstantRange(unsigned &Start, unsigned &End) const { + Start = FirstFuncConstantID; + End = FirstInstID; + } + const ValueList &getValues() const { return Values; } const TypeList &getTypes() const { return Types; } const std::vector &getBasicBlocks() const {