[llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h

Chris Lattner lattner at cs.uiuc.edu
Tue May 2 11:27:41 PDT 2006



Changes in directory llvm/include/llvm/CodeGen:

MachineCodeEmitter.h updated: 1.32 -> 1.33
---
Log message:

Refactor the machine code emitter interface to pull the pointers for the current
code emission location into the base class, instead of being in the derived classes.

This change means that low-level methods like emitByte/emitWord now are no longer
virtual (yaay for speed), and we now have a framework to support growable code 
segments.  This implements feature request #1 of PR469: http://llvm.cs.uiuc.edu/PR469 .


---
Diffs of the changes:  (+56 -16)

 MachineCodeEmitter.h |   72 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 56 insertions(+), 16 deletions(-)


Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h
diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.32 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.33
--- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.32	Tue May  2 12:17:13 2006
+++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h	Tue May  2 13:27:26 2006
@@ -31,19 +31,50 @@
 class GlobalValue;
 class Function;
 
+/// MachineCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxillary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it.  As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer.  As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit.  In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores.  Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+/// 
 class MachineCodeEmitter {
+protected:
+  /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+  /// allocated for this code buffer.
+  unsigned char *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).
+  unsigned char *CurBufferPtr;
 public:
   virtual ~MachineCodeEmitter() {}
 
   /// startFunction - This callback is invoked when the specified function is
-  /// about to be code generated.
+  /// about to be code generated.  This initializes the BufferBegin/End/Ptr
+  /// fields.
   ///
   virtual void startFunction(MachineFunction &F) {}
 
   /// finishFunction - This callback is invoked when the specified function has
-  /// finished code generation.
-  ///
-  virtual void finishFunction(MachineFunction &F) {}
+  /// finished code generation.  If a buffer overflow has occurred, this method
+  /// returns true (the callee is required to try again), otherwise it returns
+  /// false.
+  ///
+  virtual bool finishFunction(MachineFunction &F) {
+    return CurBufferPtr == BufferEnd;
+  }
 
   /// emitConstantPool - This callback is invoked to output the constant pool
   /// for the function.
@@ -63,7 +94,8 @@
   /// startFunctionStub - This callback is invoked when the JIT needs the
   /// address of a function that has not been code generated yet.  The StubSize
   /// specifies the total size required by the stub.  Stubs are not allowed to
-  /// have constant pools, the can only use the other emit* methods.
+  /// have constant pools, the can only use the other emitByte*/emitWord*
+  /// methods.
   ///
   virtual void startFunctionStub(unsigned StubSize) {}
 
@@ -75,22 +107,36 @@
   /// emitByte - This callback is invoked when a byte needs to be written to the
   /// output stream.
   ///
-  virtual void emitByte(unsigned char B) {}
+  void emitByte(unsigned char B) {
+    if (CurBufferPtr != BufferEnd)
+      *CurBufferPtr++ = B;
+  }
 
   /// emitWord - This callback is invoked when a word needs to be written to the
   /// output stream.
   ///
-  virtual void emitWord(unsigned W) = 0;
+  void emitWord(unsigned W) {
+    // FIXME: handle endian mismatches for .o file emission.
+    if (CurBufferPtr+4 <= BufferEnd) {
+      *(unsigned*)CurBufferPtr = W;
+      CurBufferPtr += 4;
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
 
   /// getCurrentPCValue - This returns the address that the next emitted byte
   /// will be output to.
   ///
-  virtual uint64_t getCurrentPCValue() = 0;
-
+  virtual intptr_t getCurrentPCValue() const {
+    return (intptr_t)CurBufferPtr;
+  }
 
   /// getCurrentPCOffset - Return the offset from the start of the emitted
   /// buffer that we are currently writing to.
-  virtual uint64_t getCurrentPCOffset() = 0;
+  intptr_t getCurrentPCOffset() const {
+    return CurBufferPtr-BufferBegin;
+  }
 
   /// addRelocation - Whenever a relocatable address is needed, it should be
   /// noted with this interface.
@@ -108,12 +154,6 @@
   
   // allocateGlobal - Allocate some space for a global variable.
   virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment) = 0;
-
-  /// createFilePrinterEmitter - Return a dynamically allocated
-  /// machine code emitter, which prints binary code to a file.  This
-  /// can be used for debugging users of the MachineCodeEmitter interface.
-  ///
-  static MachineCodeEmitter *createFilePrinterEmitter(MachineCodeEmitter&);
 };
 
 } // End llvm namespace






More information about the llvm-commits mailing list