Nicolas Geoffray
2008-Apr-05 06:16 UTC
[LLVMdev] Being able to know the jitted code-size before emitting
Evan Cheng wrote:> > Let's see. ARM has it already. PPC has getNumBytesForInstruction so > you only need to add one to compute function size. Also you only need > to implement it for targets that support JIT right now, which leaves > Alpha and X86. I'm guessing Alpha is using fixed encoding so it should > be pretty easy. Or you can just punt it and let the target maintainers > worry about it. >Yeah, fixed encoding like in PPC is easy to handle.> Really you only need to implement GetFunctionSize for X86 and that's > not as horrible as you think it is. For each instruction: > 1. Compute how many bytes of prefix. The code is there in > X86CodeEmitter except all you need is the size, not the prefixes being > emitted. > 2. For each instruction format, e.g AddRegFrm, MRMDestReg, it's either > only one single byte for opcode or one additional ModR/M byte. Again, > all the information is right there. > 3. Some memory instructions needs a SIB byte. > 4. Process the operands! Some special handling for operands that made > up of the memory address. But the logic is all there in > emitMemModRMByte. > > What do you think? > >That's doable, but I'm afraid I'll have to duplicate many code (eg emitMemModRMByte -> sizeMemModRMByte and probably others). That's not a problem (I'm thinking bug fixes and improvements, we'll have to handle two duplicated code). Nicolas> Evan > > >> >>> Suppose you have the size, can't you pass the desired buffer size to >>> MachineCodeEmitter and have it do the right thing? >>> >> Sure, that's what I'm doing. The emitter with the SizeEmitter class >> will >> give the accurate size to the MachineCodeEmitter. And the >> MachineCodeEmitter will emit the instructions in the buffer. >> >> My solution is surely using things in a way that wasn't intended, >> but it >> works fine and for all targets. Is this really a stopper for >> integrating >> it? (You can see here my laziness on implementing the >> GetFunctionSize to >> every targets :)). >> >> Nicolas >> >> >>> It seems like you >>> can add the functionality to MachineCodeEmitter rather than add a new >>> class for it. >>> >>> Evan >>> >>> >>> >>>> Nicolas >>>> >>>> >>>>> Thanks, >>>>> >>>>> Evan >>>>> >>>>> 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? >>>>>> >>>>>> 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 >>>>>> >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>> >>>>> >>>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Evan Cheng
2008-Apr-05 09:00 UTC
[LLVMdev] Being able to know the jitted code-size before emitting
On Apr 4, 2008, at 11:16 PM, Nicolas Geoffray <nicolas.geoffray at lip6.fr> wrote:> Evan Cheng wrote: >> >> Let's see. ARM has it already. PPC has getNumBytesForInstruction so >> you only need to add one to compute function size. Also you only need >> to implement it for targets that support JIT right now, which leaves >> Alpha and X86. I'm guessing Alpha is using fixed encoding so it >> should >> be pretty easy. Or you can just punt it and let the target >> maintainers >> worry about it. >> > > Yeah, fixed encoding like in PPC is easy to handle. > >> Really you only need to implement GetFunctionSize for X86 and that's >> not as horrible as you think it is. For each instruction: >> 1. Compute how many bytes of prefix. The code is there in >> X86CodeEmitter except all you need is the size, not the prefixes >> being >> emitted. >> 2. For each instruction format, e.g AddRegFrm, MRMDestReg, it's >> either >> only one single byte for opcode or one additional ModR/M byte. Again, >> all the information is right there. >> 3. Some memory instructions needs a SIB byte. >> 4. Process the operands! Some special handling for operands that made >> up of the memory address. But the logic is all there in >> emitMemModRMByte. >> >> What do you think? >> >> > > That's doable, but I'm afraid I'll have to duplicate many code (eg > emitMemModRMByte -> sizeMemModRMByte and probably others). That's > not a > problem (I'm thinking bug fixes and improvements, we'll have to handle > two duplicated code).I don't think the duplication is going to be top much of a problem. If it is, I'll bug you about refactoring. :) Thanks, Evan> > > Nicolas > >> Evan >> >> >>> >>>> Suppose you have the size, can't you pass the desired buffer size >>>> to >>>> MachineCodeEmitter and have it do the right thing? >>>> >>> Sure, that's what I'm doing. The emitter with the SizeEmitter class >>> will >>> give the accurate size to the MachineCodeEmitter. And the >>> MachineCodeEmitter will emit the instructions in the buffer. >>> >>> My solution is surely using things in a way that wasn't intended, >>> but it >>> works fine and for all targets. Is this really a stopper for >>> integrating >>> it? (You can see here my laziness on implementing the >>> GetFunctionSize to >>> every targets :)). >>> >>> Nicolas >>> >>> >>>> It seems like you >>>> can add the functionality to MachineCodeEmitter rather than add a >>>> new >>>> class for it. >>>> >>>> Evan >>>> >>>> >>>> >>>>> Nicolas >>>>> >>>>> >>>>>> Thanks, >>>>>> >>>>>> Evan >>>>>> >>>>>> 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? >>>>>>> >>>>>>> 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 >>>>>>> >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>>> >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>> >>>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Nicolas Geoffray
2008-Apr-07 10:02 UTC
[LLVMdev] Being able to know the jitted code-size before emitting
Hi Evan, Evan Cheng wrote:> > I don't think the duplication is going to be top much of a problem. If > it is, I'll bug you about refactoring. :) > >I don't mean to show how lazy I can be, but I also need to know the size of the exception table emitted in memory (JITDwarfEmitter.cpp). Reviewing it a little, I can not see how things won't be duplicated. Knowing that I already duplicated code to implement dwarf facilities to JIT... Besides, my implementation is not that slow, you know. :) It's roughly 5 times faster than the actual emission of the code. And if someone's unhappy with it, then it doesn't have to use it (or code it your way). The only downside of my implementation is the virtualization of some function calls of MachineCodeEmitter. But that does not really cost much. So I'm torn between two different approaches. I don't see one of them being cleaner than the other one: one duplicates code, one has an unusal way to do things. Moreover, if that functionality is integrated into the tree, there is little remaining for vmkit to use TOT without patching. And I would love to see that as soon as possible. So are you still strongly against it? Should I stop complaining and start writing the functionality the way you suggested it? ;-) Thx, Nicolas> Thanks, > > Evan > > >> Nicolas >> >> >>> Evan >>> >>> >>> >>>>> Suppose you have the size, can't you pass the desired buffer size >>>>> to >>>>> MachineCodeEmitter and have it do the right thing? >>>>> >>>>> >>>> Sure, that's what I'm doing. The emitter with the SizeEmitter class >>>> will >>>> give the accurate size to the MachineCodeEmitter. And the >>>> MachineCodeEmitter will emit the instructions in the buffer. >>>> >>>> My solution is surely using things in a way that wasn't intended, >>>> but it >>>> works fine and for all targets. Is this really a stopper for >>>> integrating >>>> it? (You can see here my laziness on implementing the >>>> GetFunctionSize to >>>> every targets :)). >>>> >>>> Nicolas >>>> >>>> >>>> >>>>> It seems like you >>>>> can add the functionality to MachineCodeEmitter rather than add a >>>>> new >>>>> class for it. >>>>> >>>>> Evan >>>>> >>>>> >>>>> >>>>> >>>>>> Nicolas >>>>>> >>>>>> >>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> Evan >>>>>>> >>>>>>> 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? >>>>>>>> >>>>>>>> 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 >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> LLVM Developers mailing list >>>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>>> >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>>> >>>>> >>>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Possibly Parallel Threads
- [LLVMdev] Being able to know the jitted code-size before emitting
- [LLVMdev] Being able to know the jitted code-size before emitting
- [LLVMdev] Being able to know the jitted code-size before emitting
- [LLVMdev] Being able to know the jitted code-size before emitting
- [LLVMdev] Being able to know the jitted code-size before emitting