[LLVMdev] Being able to know the jitted code-size before emitting
Evan Cheng
evan.cheng at apple.com
Sat Apr 5 02:00:21 PDT 2008
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
More information about the llvm-dev
mailing list