[LLVMdev] Being able to know the jitted code-size before emitting
Tanya Lattner
tonic at nondot.org
Sun Mar 30 15:35:52 PDT 2008
On Mar 30, 2008, at 12:05 PM, Nicolas Geoffray wrote:
> Hi everyone,
>
> vmkit requires to know the size of a jitted method before emitting
> the method. This allows to allocate the correct size for the method.
> The attached patch creates this functionality when the flag
> SizedMemoryCode is on.
>
> In order to implement this functionality, i had to virtualize some
> MachineCodeEmitter functions.
>
> Is it OK to commit the patch?
>
A couple style comments:
- The header for SizeEmitter.h is the old style. Please remove the
part about "was developed by". You can see other files for the
correct format. I think SizeEmitter.cpp is missing the header totally.
- SizeEmitter.h/SizeEmitter.cpp is lacking comments. Please add
doxygen style comments for all functions and member variables.
Thanks,
Tanya
> Thanks,
> Nicolas
> Index: include/llvm/Target/TargetOptions.h
> ===================================================================
> --- include/llvm/Target/TargetOptions.h (revision 48944)
> +++ include/llvm/Target/TargetOptions.h (working copy)
> @@ -74,6 +74,10 @@
> /// be emitted.
> extern bool ExceptionHandling;
>
> + /// SizedMemoryCode - This flags indicates that memory for code
> is allocated by
> + /// an external allocator which requires the size to allocate
> + extern bool SizedMemoryCode;
> +
> /// PerformTailCallOpt - This flag is enabled when -tailcallopt is
> specified
> /// on the commandline. When the flag is on, the target will
> perform tail call
> /// optimization (pop the caller's stack) providing it supports it.
> Index: include/llvm/CodeGen/SizeEmitter.h
> ===================================================================
> --- include/llvm/CodeGen/SizeEmitter.h (revision 0)
> +++ include/llvm/CodeGen/SizeEmitter.h (revision 0)
> @@ -0,0 +1,116 @@
> +//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*-
> 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 file defines an abstract interface that is used by the
> machine code
> +// emission framework to output the code. This allows machine code
> emission to
> +// be separated from concerns such as resolution of call targets,
> and where the
> +// machine code will be written (memory or disk, f.e.).
> +//
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +
> +#ifndef LLVM_CODEGEN_SIZEEMITTER_H
> +#define LLVM_CODEGEN_SIZEEMITTER_H
> +
> +#include "llvm/CodeGen/MachineCodeEmitter.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +
> +namespace llvm {
> + /// SizeEmitter - The JIT implementation of the
> MachineCodeEmitter, which is
> + /// used to output functions to memory for execution.
> +class SizeEmitter : public MachineCodeEmitter {
> + MachineFunction * Fn;
> + void* ConstantPoolBase;
> + void* JumpTableBase;
> + MachineConstantPool *ConstantPool;
> + MachineJumpTableInfo *JumpTable;
> + std::vector<intptr_t> LabelLocations;
> + MachineCodeEmitter* MCE;
> +
> +public:
> + SizeEmitter(MachineCodeEmitter* mce) {
> + CurBufferPtr = 0;
> + BufferBegin = 0;
> + BufferEnd = (unsigned char*)-1;
> + MCE = mce;
> + }
> +
> + SizeEmitter(std::vector<intptr_t> locations) {
> + LabelLocations = locations;
> + CurBufferPtr = 0;
> + BufferBegin = 0;
> + BufferEnd = (unsigned char*)-1;
> + }
> +
> + void initConstantPool(MachineConstantPool *MCP);
> +
> + void initJumpTableInfo(MachineJumpTableInfo *MJTI);
> +
> +
> + virtual void startFunction(MachineFunction &F) {
> + CurBufferPtr = 0;
> + Fn = &F;
> +
> + // Ensure the constant pool/jump table info is at least 4-byte
> aligned.
> + emitAlignment(16);
> +
> + initConstantPool(F.getConstantPool());
> + initJumpTableInfo(F.getJumpTableInfo());
> +
> + ConstantPoolBase = (void*)(((uintptr_t) ConstantPoolBase) +
> CurBufferPtr);
> + JumpTableBase = (void*)(((uintptr_t) JumpTableBase) +
> CurBufferPtr);
> + }
> +
> + virtual bool finishFunction(MachineFunction &F) {
> + MCE->setCurrentPtr(CurBufferPtr);
> + return false;
> + }
> + virtual void startFunctionStub(unsigned StubSize, unsigned
> Alignment) {}
> + virtual void *finishFunctionStub(const Function *F) { return 0; }
> + virtual void addRelocation(const llvm::MachineRelocation&) { }
> + virtual void emitByte(unsigned char B) {
> + CurBufferPtr++;
> + }
> + virtual void emitWordLE(unsigned W) {
> + CurBufferPtr+=4;
> + }
> + virtual void emitWordBE(unsigned W) {
> + CurBufferPtr+=4;
> + }
> + virtual void emitInt32(int Value) {
> + CurBufferPtr += 4;
> + }
> + virtual void emitInt64(uint64_t Value) {
> + CurBufferPtr += 8;
> + }
> + virtual void emitAt(uintptr_t *Addr, uintptr_t Value) {
> + }
> +
> +
> +
> + virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
> + virtual intptr_t getConstantPoolEntryAddress(unsigned
> ConstantNum) const;
> +
> + virtual intptr_t getJumpTableEntryAddress(unsigned Index) const;
> +
> + virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock
> *MBB) const {
> + assert(0 && "Should not be in getMachineBasicBlockAddress of
> SizeEmitter");
> + }
> +
> + virtual void emitLabel(uint64_t) {}
> + virtual intptr_t getLabelAddress(uint64_t LabelID) const {
> + assert(LabelLocations.size() > (unsigned)LabelID &&
> + LabelLocations[LabelID] && "Label not emitted!");
> + return LabelLocations[LabelID];
> + }
> + virtual void setModuleInfo(llvm::MachineModuleInfo*) {}
> +};
> +
> +} // end llvm namespace
> +
> +#endif
> Index: include/llvm/CodeGen/MachineCodeEmitter.h
> ===================================================================
> --- include/llvm/CodeGen/MachineCodeEmitter.h (revision 48143)
> +++ include/llvm/CodeGen/MachineCodeEmitter.h (working copy)
> @@ -18,6 +18,7 @@
> #define LLVM_CODEGEN_MACHINECODEEMITTER_H
>
> #include "llvm/Support/DataTypes.h"
> +#include <string>
> #include <vector>
>
> namespace llvm {
> @@ -92,7 +93,7 @@
> /// emitByte - This callback is invoked when a byte needs to be
> written to the
> /// output stream.
> ///
> - void emitByte(unsigned char B) {
> + virtual void emitByte(unsigned char B) {
> if (CurBufferPtr != BufferEnd)
> *CurBufferPtr++ = B;
> }
> @@ -100,7 +101,7 @@
> /// emitWordLE - This callback is invoked when a 32-bit word needs
> to be
> /// written to the output stream in little-endian format.
> ///
> - void emitWordLE(unsigned W) {
> + virtual void emitWordLE(unsigned W) {
> if (CurBufferPtr+4 <= BufferEnd) {
> *CurBufferPtr++ = (unsigned char)(W >> 0);
> *CurBufferPtr++ = (unsigned char)(W >> 8);
> @@ -114,7 +115,7 @@
> /// emitWordBE - This callback is invoked when a 32-bit word needs
> to be
> /// written to the output stream in big-endian format.
> ///
> - void emitWordBE(unsigned W) {
> + virtual void emitWordBE(unsigned W) {
> if (CurBufferPtr+4 <= BufferEnd) {
> *CurBufferPtr++ = (unsigned char)(W >> 24);
> *CurBufferPtr++ = (unsigned char)(W >> 16);
> @@ -175,7 +176,7 @@
> }
>
> /// emitInt32 - Emit a int32 directive.
> - void emitInt32(int Value) {
> + virtual void emitInt32(int Value) {
> if (CurBufferPtr+4 <= BufferEnd) {
> *((uint32_t*)CurBufferPtr) = Value;
> CurBufferPtr += 4;
> @@ -185,7 +186,7 @@
> }
>
> /// emitInt64 - Emit a int64 directive.
> - void emitInt64(uint64_t Value) {
> + virtual void emitInt64(uint64_t Value) {
> if (CurBufferPtr+8 <= BufferEnd) {
> *((uint64_t*)CurBufferPtr) = Value;
> CurBufferPtr += 8;
> @@ -195,7 +196,7 @@
> }
>
> /// emitAt - Emit Value in Addr
> - void emitAt(uintptr_t *Addr, uintptr_t Value) {
> + virtual void emitAt(uintptr_t *Addr, uintptr_t Value) {
> if (Addr >= (uintptr_t*)BufferBegin && Addr <
> (uintptr_t*)BufferEnd)
> (*Addr) = Value;
> }
> @@ -270,6 +271,11 @@
> /// Specifies the MachineModuleInfo object. This is used for
> exception handling
> /// purposes.
> virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
> +
> + void setCurrentPtr(unsigned char* Ptr) {
> + CurBufferPtr = Ptr;
> + }
> +
> };
>
> } // End llvm namespace
> Index: lib/CodeGen/LLVMTargetMachine.cpp
> ===================================================================
> --- lib/CodeGen/LLVMTargetMachine.cpp (revision 48143)
> +++ lib/CodeGen/LLVMTargetMachine.cpp (working copy)
> @@ -17,6 +17,7 @@
> #include "llvm/Assembly/PrintModulePass.h"
> #include "llvm/Analysis/LoopPass.h"
> #include "llvm/CodeGen/Passes.h"
> +#include "llvm/CodeGen/SizeEmitter.h"
> #include "llvm/CodeGen/Collector.h"
> #include "llvm/Target/TargetOptions.h"
> #include "llvm/Transforms/Scalar.h"
> @@ -257,7 +258,13 @@
>
> if (addPreEmitPass(PM, Fast) && PrintMachineCode)
> PM.add(createMachineFunctionPrinterPass(cerr));
> +
> + if (SizedMemoryCode) {
> + SizeEmitter * SE = new SizeEmitter(&MCE);
> + addSimpleCodeEmitter(PM, Fast, false, *SE);
> + }
>
> +
> addCodeEmitter(PM, Fast, PrintEmittedAsm, MCE);
>
> PM.add(createCollectorMetadataDeleter());
> Index: lib/CodeGen/SizeEmitter.cpp
> ===================================================================
> --- lib/CodeGen/SizeEmitter.cpp (revision 0)
> +++ lib/CodeGen/SizeEmitter.cpp (revision 0)
> @@ -0,0 +1,77 @@
> +#include "llvm/CodeGen/SizeEmitter.h"
> +#include "llvm/Constant.h"
> +#include "llvm/Constants.h"
> +#include "llvm/DerivedTypes.h"
> +#include "llvm/Module.h"
> +#include "llvm/Type.h"
> +#include "llvm/CodeGen/MachineCodeEmitter.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineConstantPool.h"
> +#include "llvm/CodeGen/MachineJumpTableInfo.h"
> +#include "llvm/CodeGen/MachineRelocation.h"
> +#include "llvm/ExecutionEngine/GenericValue.h"
> +#include "llvm/Target/TargetData.h"
> +#include "llvm/Target/TargetJITInfo.h"
> +#include "llvm/Target/TargetMachine.h"
> +#include "llvm/Target/TargetOptions.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/MutexGuard.h"
> +#include "llvm/System/Disassembler.h"
> +#include "llvm/ADT/Statistic.h"
> +#include "llvm/System/Memory.h"
> +#include <algorithm>
> +using namespace llvm;
> +
> +
> +void SizeEmitter::initConstantPool(MachineConstantPool *MCP) {
> + const std::vector<MachineConstantPoolEntry> &Constants = MCP-
> >getConstants();
> + if (Constants.empty()) return;
> +
> + MachineConstantPoolEntry CPE = Constants.back();
> + unsigned Size = CPE.Offset;
> + const Type *Ty = CPE.isMachineConstantPoolEntry()
> + ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType();
> + Size += Fn->getTarget().getTargetData()->getABITypeSize(Ty);
> + ConstantPoolBase = allocateSpace(Size, 1 << MCP-
> >getConstantPoolAlignment());
> + ConstantPool = MCP;
> +}
> +
> +void SizeEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
> + const std::vector<MachineJumpTableEntry> &JT = MJTI-
> >getJumpTables();
> + if (JT.empty()) return;
> +
> + unsigned NumEntries = 0;
> + for (unsigned i = 0, e = JT.size(); i != e; ++i)
> + NumEntries += JT[i].MBBs.size();
> +
> + unsigned EntrySize = MJTI->getEntrySize();
> +
> + // Just allocate space for all the jump tables now. We will fix
> up the actual
> + // MBB entries in the tables after we emit the code for each
> block, since then
> + // we will know the final locations of the MBBs in memory.
> + JumpTable = MJTI;
> + JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI-
> >getAlignment());
> +}
> +
> +intptr_t SizeEmitter::getConstantPoolEntryAddress(unsigned
> ConstantNum) const {
> + assert(ConstantNum < ConstantPool->getConstants().size() &&
> + "Invalid ConstantPoolIndex!");
> + return (intptr_t)ConstantPoolBase +
> + ConstantPool->getConstants()[ConstantNum].Offset;
> +}
> +
> +intptr_t SizeEmitter::getJumpTableEntryAddress(unsigned Index)
> const {
> + const std::vector<MachineJumpTableEntry> &JT = JumpTable-
> >getJumpTables();
> + assert(Index < JT.size() && "Invalid jump table index!");
> +
> + unsigned Offset = 0;
> + unsigned EntrySize = JumpTable->getEntrySize();
> +
> + for (unsigned i = 0; i < Index; ++i)
> + Offset += JT[i].MBBs.size();
> +
> + Offset *= EntrySize;
> +
> + return (intptr_t)((char *)JumpTableBase + Offset);
> +}
> +
> Index: lib/Target/TargetMachine.cpp
> ===================================================================
> --- lib/Target/TargetMachine.cpp (revision 48143)
> +++ lib/Target/TargetMachine.cpp (working copy)
> @@ -31,6 +31,7 @@
> bool UseSoftFloat;
> bool NoZerosInBSS;
> bool ExceptionHandling;
> + bool SizedMemoryCode;
> Reloc::Model RelocationModel;
> CodeModel::Model CMModel;
> bool PerformTailCallOpt;
> Index: lib/ExecutionEngine/JIT/JITEmitter.cpp
> ===================================================================
> --- lib/ExecutionEngine/JIT/JITEmitter.cpp (revision 48143)
> +++ lib/ExecutionEngine/JIT/JITEmitter.cpp (working copy)
> @@ -18,12 +18,14 @@
> #include "llvm/Constant.h"
> #include "llvm/Module.h"
> #include "llvm/Type.h"
> +#include "llvm/ADT/DenseMap.h"
> #include "llvm/CodeGen/MachineCodeEmitter.h"
> #include "llvm/CodeGen/MachineFunction.h"
> #include "llvm/CodeGen/MachineConstantPool.h"
> #include "llvm/CodeGen/MachineJumpTableInfo.h"
> #include "llvm/CodeGen/MachineModuleInfo.h"
> #include "llvm/CodeGen/MachineRelocation.h"
> +#include "llvm/CodeGen/SizeEmitter.h"
> #include "llvm/ExecutionEngine/JITMemoryManager.h"
> #include "llvm/Target/TargetData.h"
> #include "llvm/Target/TargetJITInfo.h"
> @@ -370,6 +376,7 @@
> virtual void startFunction(MachineFunction &F);
> virtual bool finishFunction(MachineFunction &F);
>
> + void initConstantPool(MachineConstantPool *MCP);
> void emitConstantPool(MachineConstantPool *MCP);
> void initJumpTableInfo(MachineJumpTableInfo *MJTI);
> void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
> @@ -469,19 +476,47 @@
>
>
> void JITEmitter::startFunction(MachineFunction &F) {
> - uintptr_t ActualSize;
> - BufferBegin = CurBufferPtr = MemMgr-
> >startFunctionBody(F.getFunction(),
> - ActualSize);
> - BufferEnd = BufferBegin+ActualSize;
> + MMI->BeginFunction(&F);
>
> - // Ensure the constant pool/jump table info is at least 4-byte
> aligned.
> - emitAlignment(16);
> + if (SizedMemoryCode) {
> + BufferBegin = CurBufferPtr;
> + BufferEnd = (unsigned char*) 0xffffffff;
> +
> + // Ensure the constant pool/jump table info is at least 4-byte
> aligned.
> + emitAlignment(16);
>
> - emitConstantPool(F.getConstantPool());
> - initJumpTableInfo(F.getJumpTableInfo());
> + initConstantPool(F.getConstantPool());
> + initJumpTableInfo(F.getJumpTableInfo());
> +
> +
> + uintptr_t ActualSize = (uintptr_t)CurBufferPtr;
> + CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
> + ActualSize);
> +
> + ConstantPoolBase = (void*)(((unsigned) ConstantPoolBase) +
> CurBufferPtr);
> + JumpTableBase = (void*)(((unsigned) JumpTableBase) +
> CurBufferPtr);
>
> - // About to start emitting the machine code for the function.
> - emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
> + emitConstantPool(F.getConstantPool());
> +
> + } else {
> + uintptr_t ActualSize;
> + BufferBegin = CurBufferPtr = MemMgr-
> >startFunctionBody(F.getFunction(),
> +
> ActualSize);
> + BufferEnd = BufferBegin+ActualSize;
> +
> + // Ensure the constant pool/jump table info is at least 4-byte
> aligned.
> + emitAlignment(16);
> +
> + initConstantPool(F.getConstantPool());
> + emitConstantPool(F.getConstantPool());
> + initJumpTableInfo(F.getJumpTableInfo());
> +
> + // About to start emitting the machine code for the function.
> + emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
> +
> + }
> +
> +
> TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
>
> MBBLocations.clear();
> @@ -579,12 +614,18 @@
> DOUT << "Disassembled code:\n"
> << sys::disassembleBuffer(FnStart, FnEnd-FnStart,
> (uintptr_t)FnStart);
> #endif
> +
> if (ExceptionHandling) {
> uintptr_t ActualSize;
> + if (SizedMemoryCode) {
> + SizeEmitter sz(LabelLocations);
> + DE->EmitDwarfTable(F, sz, FnStart, FnEnd);
> + ActualSize = sz.getCurrentPCValue();
> + }
> SavedBufferBegin = BufferBegin;
> SavedBufferEnd = BufferEnd;
> SavedCurBufferPtr = CurBufferPtr;
> -
> +
> BufferBegin = CurBufferPtr = MemMgr-
> >startExceptionTable(F.getFunction(),
>
> ActualSize);
> BufferEnd = BufferBegin+ActualSize;
> @@ -598,11 +639,10 @@
> TheJIT->RegisterTable(FrameRegister);
> }
> MMI->EndFunction();
> -
> return false;
> }
>
> -void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
> +void JITEmitter::initConstantPool(MachineConstantPool *MCP) {
> const std::vector<MachineConstantPoolEntry> &Constants = MCP-
> >getConstants();
> if (Constants.empty()) return;
>
> @@ -611,12 +651,15 @@
> const Type *Ty = CPE.isMachineConstantPoolEntry()
> ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType();
> Size += TheJIT->getTargetData()->getABITypeSize(Ty);
> -
> +
> ConstantPoolBase = allocateSpace(Size, 1 << MCP-
> >getConstantPoolAlignment());
> ConstantPool = MCP;
> +}
>
> +void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
> if (ConstantPoolBase == 0) return; // Buffer overflow.
>
> + const std::vector<MachineConstantPoolEntry> &Constants = MCP-
> >getConstants();
> // Initialize the memory for all of the constant pool entries.
> for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
> void *CAddr = (char*)ConstantPoolBase+Constants[i].Offset;
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
More information about the llvm-dev
mailing list