[llvm-commits] [llvm] r91464 - in /llvm/trunk: include/llvm/CodeGen/JITCodeEmitter.h include/llvm/CodeGen/MachineCodeEmitter.h lib/ExecutionEngine/JIT/JITEmitter.cpp lib/Target/ARM/ARMJITInfo.cpp lib/Target/Alpha/AlphaJITInfo.cpp lib/Target/PowerPC/PPCJITInfo.cpp lib/Target/X86/X86JITInfo.cpp

Jeffrey Yasskin jyasskin at google.com
Tue Dec 15 14:42:46 PST 2009


Author: jyasskin
Date: Tue Dec 15 16:42:46 2009
New Revision: 91464

URL: http://llvm.org/viewvc/llvm-project?rev=91464&view=rev
Log:
Change indirect-globals to use a dedicated allocIndirectGV.  This lets us
remove start/finishGVStub and the BufferState helper class from the
MachineCodeEmitter interface.  It has the side-effect of not setting the
indirect global writable and then executable on ARM, but that shouldn't be
necessary.

Modified:
    llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h
    llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
    llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp
    llvm/trunk/lib/Target/Alpha/AlphaJITInfo.cpp
    llvm/trunk/lib/Target/PowerPC/PPCJITInfo.cpp
    llvm/trunk/lib/Target/X86/X86JITInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h Tue Dec 15 16:42:46 2009
@@ -68,29 +68,11 @@
   ///
   virtual bool finishFunction(MachineFunction &F) = 0;
   
-  /// startGVStub - This callback is invoked when the JIT needs the address of a
-  /// GV (e.g. function) that has not been code generated yet.  The StubSize
-  /// specifies the total size required by the stub.  The BufferState must be
-  /// passed to finishGVStub, and start/finish pairs with the same BufferState
-  /// must be properly nested.
-  ///
-  virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
-                           unsigned StubSize, unsigned Alignment = 1) = 0;
-
-  /// startGVStub - This callback is invoked when the JIT needs the address of a
-  /// GV (e.g. function) that has not been code generated yet.  Buffer points to
-  /// memory already allocated for this stub.  The BufferState must be passed to
-  /// finishGVStub, and start/finish pairs with the same BufferState must be
-  /// properly nested.
-  ///
-  virtual void startGVStub(BufferState &BS, void *Buffer,
-                           unsigned StubSize) = 0;
-
-  /// finishGVStub - This callback is invoked to terminate a GV stub and returns
-  /// the start address of the stub.  The BufferState must first have been
-  /// passed to startGVStub.
-  ///
-  virtual void *finishGVStub(BufferState &BS) = 0;
+  /// allocIndirectGV - Allocates and fills storage for an indirect
+  /// GlobalValue, and returns the address.
+  virtual void *allocIndirectGV(const GlobalValue *GV,
+                                const uint8_t *Buffer, size_t Size,
+                                unsigned Alignment) = 0;
 
   /// emitByte - This callback is invoked when a byte needs to be written to the
   /// output stream.

Modified: llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h Tue Dec 15 16:42:46 2009
@@ -48,41 +48,16 @@
 /// occurred, more memory is allocated, and we reemit the code into it.
 /// 
 class MachineCodeEmitter {
-public:
-  class BufferState {
-    friend class MachineCodeEmitter;
-    /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
-    /// allocated for this code buffer.
-    uint8_t *BufferBegin, *BufferEnd;
-
-    /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
-    /// code.  This is guranteed to be in the range [BufferBegin,BufferEnd].  If
-    /// this pointer is at BufferEnd, it will never move due to code emission,
-    /// and all code emission requests will be ignored (this is the buffer
-    /// overflow condition).
-    uint8_t *CurBufferPtr;
-  public:
-    BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {}
-  };
-
 protected:
-  /// These have the same meanings as the fields in BufferState
-  uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr;
-
-  /// Save or restore the current buffer state.  The BufferState objects must be
-  /// used as a stack.
-  void SaveStateTo(BufferState &BS) {
-    assert(BS.BufferBegin == NULL &&
-           "Can't save state into the same BufferState twice.");
-    BS.BufferBegin = BufferBegin;
-    BS.BufferEnd = BufferEnd;
-    BS.CurBufferPtr = CurBufferPtr;
-  }
-  void RestoreStateFrom(BufferState &BS) {
-    BufferBegin = BS.BufferBegin;
-    BufferEnd = BS.BufferEnd;
-    CurBufferPtr = BS.CurBufferPtr;
-  }
+  /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+  /// allocated for this code buffer.
+  uint8_t *BufferBegin, *BufferEnd;
+  /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+  /// code.  This is guranteed to be in the range [BufferBegin,BufferEnd].  If
+  /// this pointer is at BufferEnd, it will never move due to code emission, and
+  /// all code emission requests will be ignored (this is the buffer overflow
+  /// condition).
+  uint8_t *CurBufferPtr;
 
 public:
   virtual ~MachineCodeEmitter() {}
@@ -113,15 +88,23 @@
   ///
   void emitWordLE(uint32_t W) {
     if (4 <= BufferEnd-CurBufferPtr) {
-      *CurBufferPtr++ = (uint8_t)(W >>  0);
-      *CurBufferPtr++ = (uint8_t)(W >>  8);
-      *CurBufferPtr++ = (uint8_t)(W >> 16);
-      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      emitWordLEInto(CurBufferPtr, W);
     } else {
       CurBufferPtr = BufferEnd;
     }
   }
-  
+
+  /// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
+  /// written to an arbitrary buffer in little-endian format.  Buf must have at
+  /// least 4 bytes of available space.
+  ///
+  static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
+    *Buf++ = (uint8_t)(W >>  0);
+    *Buf++ = (uint8_t)(W >>  8);
+    *Buf++ = (uint8_t)(W >> 16);
+    *Buf++ = (uint8_t)(W >> 24);
+  }
+
   /// emitWordBE - This callback is invoked when a 32-bit word needs to be
   /// written to the output stream in big-endian format.
   ///

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Dec 15 16:42:46 2009
@@ -271,6 +271,10 @@
   class JITEmitter : public JITCodeEmitter {
     JITMemoryManager *MemMgr;
 
+    // When outputting a function stub in the context of some other function, we
+    // save BufferBegin/BufferEnd/CurBufferPtr here.
+    uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
+
     // When reattempting to JIT a function after running out of space, we store
     // the estimated size of the function we're trying to JIT here, so we can
     // ask the memory manager for at least this much space.  When we
@@ -396,11 +400,13 @@
     void initJumpTableInfo(MachineJumpTableInfo *MJTI);
     void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
 
-    virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
-                             unsigned StubSize, unsigned Alignment = 1);
-    virtual void startGVStub(BufferState &BS, void *Buffer,
-                             unsigned StubSize);
-    virtual void* finishGVStub(BufferState &BS);
+    void startGVStub(const GlobalValue* GV,
+                     unsigned StubSize, unsigned Alignment = 1);
+    void startGVStub(void *Buffer, unsigned StubSize);
+    void finishGVStub();
+    virtual void *allocIndirectGV(const GlobalValue *GV,
+                                  const uint8_t *Buffer, size_t Size,
+                                  unsigned Alignment);
 
     /// allocateSpace - Reserves space in the current block if any, or
     /// allocate a new one of the given size.
@@ -521,13 +527,12 @@
     if (!Actual) return 0;
   }
 
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
-  JE.startGVStub(BS, F, SL.Size, SL.Alignment);
+  JE.startGVStub(F, SL.Size, SL.Alignment);
   // Codegen a new stub, calling the lazy resolver or the actual address of the
   // external function, if it was resolved.
   Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE);
-  JE.finishGVStub(BS);
+  JE.finishGVStub();
 
   if (Actual != (void*)(intptr_t)LazyResolverFn) {
     // If we are getting the stub for an external function, we really want the
@@ -579,11 +584,10 @@
   void *&Stub = ExternalFnToStubMap[FnAddr];
   if (Stub) return Stub;
 
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
-  JE.startGVStub(BS, 0, SL.Size, SL.Alignment);
+  JE.startGVStub(0, SL.Size, SL.Alignment);
   Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
-  JE.finishGVStub(BS);
+  JE.finishGVStub();
 
   DEBUG(errs() << "JIT: Stub emitted at [" << Stub
                << "] for external function at '" << FnAddr << "'\n");
@@ -1215,8 +1219,9 @@
 
   if (DwarfExceptionHandling || JITEmitDebugInfo) {
     uintptr_t ActualSize = 0;
-    BufferState BS;
-    SaveStateTo(BS);
+    SavedBufferBegin = BufferBegin;
+    SavedBufferEnd = BufferEnd;
+    SavedCurBufferPtr = CurBufferPtr;
 
     if (MemMgr->NeedsExactSize()) {
       ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
@@ -1232,7 +1237,9 @@
     MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
                               FrameRegister);
     uint8_t *EhEnd = CurBufferPtr;
-    RestoreStateFrom(BS);
+    BufferBegin = SavedBufferBegin;
+    BufferEnd = SavedBufferEnd;
+    CurBufferPtr = SavedCurBufferPtr;
 
     if (DwarfExceptionHandling) {
       TheJIT->RegisterTable(FrameRegister);
@@ -1438,27 +1445,39 @@
   }
 }
 
-void JITEmitter::startGVStub(BufferState &BS, const GlobalValue* GV,
+void JITEmitter::startGVStub(const GlobalValue* GV,
                              unsigned StubSize, unsigned Alignment) {
-  SaveStateTo(BS);
+  SavedBufferBegin = BufferBegin;
+  SavedBufferEnd = BufferEnd;
+  SavedCurBufferPtr = CurBufferPtr;
 
   BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
   BufferEnd = BufferBegin+StubSize+1;
 }
 
-void JITEmitter::startGVStub(BufferState &BS, void *Buffer, unsigned StubSize) {
-  SaveStateTo(BS);
+void JITEmitter::startGVStub(void *Buffer, unsigned StubSize) {
+  SavedBufferBegin = BufferBegin;
+  SavedBufferEnd = BufferEnd;
+  SavedCurBufferPtr = CurBufferPtr;
 
   BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
   BufferEnd = BufferBegin+StubSize+1;
 }
 
-void *JITEmitter::finishGVStub(BufferState &BS) {
+void JITEmitter::finishGVStub() {
   assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
   NumBytes += getCurrentPCOffset();
-  void *Result = BufferBegin;
-  RestoreStateFrom(BS);
-  return Result;
+  BufferBegin = SavedBufferBegin;
+  BufferEnd = SavedBufferEnd;
+  CurBufferPtr = SavedCurBufferPtr;
+}
+
+void *JITEmitter::allocIndirectGV(const GlobalValue *GV,
+                                  const uint8_t *Buffer, size_t Size,
+                                  unsigned Alignment) {
+  uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment);
+  memcpy(IndGV, Buffer, Size);
+  return IndGV;
 }
 
 // getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
@@ -1546,11 +1565,10 @@
 
   // Tell the target jit info to rewrite the stub at the specified address,
   // rather than creating a new one.
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout();
-  JE->startGVStub(BS, Stub, layout.Size);
+  JE->startGVStub(Stub, layout.Size);
   getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter());
-  JE->finishGVStub(BS);
+  JE->finishGVStub();
 }
 
 /// freeMachineCodeForFunction - release machine code memory for given Function.

Modified: llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp Tue Dec 15 16:42:46 2009
@@ -139,17 +139,11 @@
 
 void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,
                                              JITCodeEmitter &JCE) {
-  MachineCodeEmitter::BufferState BS;
-  JCE.startGVStub(BS, GV, 4, 4);
-  intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();
-  if (!sys::Memory::setRangeWritable((void*)Addr, 4)) {
-    llvm_unreachable("ERROR: Unable to mark indirect symbol writable");
-  }
-  JCE.emitWordLE((intptr_t)Ptr);
-  if (!sys::Memory::setRangeExecutable((void*)Addr, 4)) {
-    llvm_unreachable("ERROR: Unable to mark indirect symbol executable");
-  }
-  void *PtrAddr = JCE.finishGVStub(BS);
+  uint8_t Buffer[4];
+  uint8_t *Cur = Buffer;
+  MachineCodeEmitter::emitWordLEInto(Cur, (intptr_t)Ptr);
+  void *PtrAddr = JCE.allocIndirectGV(
+      GV, Buffer, sizeof(Buffer), /*Alignment=*/4);
   addIndirectSymAddr(Ptr, (intptr_t)PtrAddr);
   return PtrAddr;
 }

Modified: llvm/trunk/lib/Target/Alpha/AlphaJITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaJITInfo.cpp?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Alpha/AlphaJITInfo.cpp (original)
+++ llvm/trunk/lib/Target/Alpha/AlphaJITInfo.cpp Tue Dec 15 16:42:46 2009
@@ -202,7 +202,6 @@
 
 void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
                                      JITCodeEmitter &JCE) {
-  MachineCodeEmitter::BufferState BS;
   //assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
   //Do things in a stupid slow way!
   void* Addr = (void*)(intptr_t)JCE.getCurrentPCValue();

Modified: llvm/trunk/lib/Target/PowerPC/PPCJITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCJITInfo.cpp?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCJITInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCJITInfo.cpp Tue Dec 15 16:42:46 2009
@@ -339,7 +339,6 @@
 
 void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
                                    JITCodeEmitter &JCE) {
-  MachineCodeEmitter::BufferState BS;
   // If this is just a call to an external function, emit a branch instead of a
   // call.  The code is the same except for one bit of the last instruction.
   if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 

Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.cpp?rev=91464&r1=91463&r2=91464&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.cpp Tue Dec 15 16:42:46 2009
@@ -426,16 +426,19 @@
 
 void *X86JITInfo::emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
                                              JITCodeEmitter &JCE) {
-  MachineCodeEmitter::BufferState BS;
 #if defined (X86_64_JIT)
-  JCE.startGVStub(BS, GV, 8, 8);
-  JCE.emitWordLE((unsigned)(intptr_t)ptr);
-  JCE.emitWordLE((unsigned)(((intptr_t)ptr) >> 32));
-#else
-  JCE.startGVStub(BS, GV, 4, 4);
-  JCE.emitWordLE((intptr_t)ptr);
+  const unsigned Alignment = 8;
+  uint8_t Buffer[8];
+  uint8_t *Cur = Buffer;
+  MachineCodeEmitter::emitWordLEInto(Cur, (unsigned)(intptr_t)ptr);
+  MachineCodeEmitter::emitWordLEInto(Cur, (unsigned)(((intptr_t)ptr) >> 32));
+#else
+  const unsigned Alignment = 4;
+  uint8_t Buffer[4];
+  uint8_t *Cur = Buffer;
+  MachineCodeEmitter::emitWordLEInto(Cur, (intptr_t)ptr);
 #endif
-  return JCE.finishGVStub(BS);
+  return JCE.allocIndirectGV(GV, Buffer, sizeof(Buffer), Alignment);
 }
 
 TargetJITInfo::StubLayout X86JITInfo::getStubLayout() {
@@ -451,7 +454,6 @@
 
 void *X86JITInfo::emitFunctionStub(const Function* F, void *Target,
                                    JITCodeEmitter &JCE) {
-  MachineCodeEmitter::BufferState BS;
   // Note, we cast to intptr_t here to silence a -pedantic warning that 
   // complains about casting a function pointer to a normal pointer.
 #if defined (X86_32_JIT) && !defined (_MSC_VER)





More information about the llvm-commits mailing list