//===- WriterInternals.h - Data structures shared by the Writer -*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This header defines the interface used between components of the bytecode // writer. // // Note that the performance of this library is not terribly important, because // it shouldn't be used by JIT type applications... so it is not a huge focus // at least. :) // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_BYTECODE_WRITER_WRITERINTERNALS_H #define LLVM_LIB_BYTECODE_WRITER_WRITERINTERNALS_H #include "llvm/Bytecode/Writer.h" #include "WriterPrimitives.h" #include "llvm/Bytecode/Format.h" #include "llvm/Analysis/SlotCalculator.h" #include "llvm/Instruction.h" namespace llvm { class BytecodeWriter { std::deque &Out; SlotCalculator Table; public: BytecodeWriter(std::deque &o, const Module *M); private: void outputConstants(bool isFunction); void outputConstantStrings(); void outputFunction(const Function *F); void outputCompactionTable(); void outputCompactionTablePlane(unsigned PlaneNo, const std::vector &TypePlane, unsigned StartNo); void outputInstructions(const Function *F); void outputInstruction(const Instruction &I); void outputModuleInfoBlock(const Module *C); void outputSymbolTable(const SymbolTable &ST); void outputConstantsInPlane(const std::vector &Plane, unsigned StartNo); void outputConstant(const Constant *CPV); void outputType(const Type *T); }; /// BytecodeBlock - Little helper class is used by the bytecode writer to help /// do backpatching of bytecode block sizes really easily. It backpatches when /// it goes out of scope. /// class BytecodeBlock { unsigned Loc; std::deque &Out; /// ElideIfEmpty - If this is true and the bytecode block ends up being empty, /// the block can remove itself from the output stream entirely. bool ElideIfEmpty; BytecodeBlock(const BytecodeBlock &); // do not implement void operator=(const BytecodeBlock &); // do not implement public: inline BytecodeBlock(unsigned ID, std::deque &o, bool elideIfEmpty = false) : Out(o), ElideIfEmpty(elideIfEmpty) { output(ID, Out); output(0U, Out); // Reserve the space for the block size... Loc = Out.size(); } inline ~BytecodeBlock() { // Do backpatch when block goes out // of scope... if (Loc == Out.size() && ElideIfEmpty) { // If the block is empty, and we are allowed to, do not emit the block at // all! Out.resize(Out.size()-8); return; } //cerr << "OldLoc = " << Loc << " NewLoc = " << NewLoc << " diff = " // << (NewLoc-Loc) << endl; output(unsigned(Out.size()-Loc), Out, int(Loc-4)); align32(Out); // Blocks must ALWAYS be aligned } }; } // End llvm namespace #endif