[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