[llvm-commits] [llvm] r74813 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/PowerPC/ lib/Target/X86/ tools/llc/ tools/lto/

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Sun Jul 5 22:14:39 PDT 2009


Aaron asked me to include the original patch documentation, attached now.

On Mon, Jul 6, 2009 at 2:09 AM, Bruno Cardoso
Lopes<bruno.cardoso at gmail.com> wrote:
> Author: bruno
> Date: Mon Jul  6 00:09:34 2009
> New Revision: 74813
>
> URL: http://llvm.org/viewvc/llvm-project?rev=74813&view=rev
> Log:
> Add the Object Code Emitter class. Original patch by Aaron Gray, I did some
> cleanup, removed some #includes and moved Object Code Emitter out-of-line.
>
>
> Modified:
>    llvm/trunk/include/llvm/CodeGen/BinaryObject.h
>    llvm/trunk/include/llvm/CodeGen/FileWriters.h
>    llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
>    llvm/trunk/include/llvm/Target/TargetMachine.h
>    llvm/trunk/lib/CodeGen/ELFWriter.cpp
>    llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
>    llvm/trunk/lib/CodeGen/MachO.h
>    llvm/trunk/lib/CodeGen/MachOCodeEmitter.cpp
>    llvm/trunk/lib/CodeGen/MachOCodeEmitter.h
>    llvm/trunk/lib/CodeGen/MachOWriter.cpp
>    llvm/trunk/lib/CodeGen/MachOWriter.h
>    llvm/trunk/lib/Target/ARM/ARM.h
>    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
>    llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
>    llvm/trunk/lib/Target/ARM/ARMTargetMachine.h
>    llvm/trunk/lib/Target/Alpha/Alpha.h
>    llvm/trunk/lib/Target/Alpha/AlphaCodeEmitter.cpp
>    llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.cpp
>    llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.h
>    llvm/trunk/lib/Target/PowerPC/PPC.h
>    llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp
>    llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
>    llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h
>    llvm/trunk/lib/Target/X86/X86.h
>    llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
>    llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
>    llvm/trunk/lib/Target/X86/X86TargetMachine.h
>    llvm/trunk/tools/llc/llc.cpp
>    llvm/trunk/tools/lto/LTOCodeGenerator.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/BinaryObject.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/BinaryObject.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/BinaryObject.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/BinaryObject.h Mon Jul  6 00:09:34 2009
> @@ -146,27 +146,27 @@
>   /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
>   /// written to the data stream in little-endian format.
>   inline void emitDWordLE(uint64_t W) {
> -    Data.push_back(unsigned(W >>  0) & 255);
> -    Data.push_back(unsigned(W >>  8) & 255);
> -    Data.push_back(unsigned(W >> 16) & 255);
> -    Data.push_back(unsigned(W >> 24) & 255);
> -    Data.push_back(unsigned(W >> 32) & 255);
> -    Data.push_back(unsigned(W >> 40) & 255);
> -    Data.push_back(unsigned(W >> 48) & 255);
> -    Data.push_back(unsigned(W >> 56) & 255);
> +    Data.push_back((W >>  0) & 255);
> +    Data.push_back((W >>  8) & 255);
> +    Data.push_back((W >> 16) & 255);
> +    Data.push_back((W >> 24) & 255);
> +    Data.push_back((W >> 32) & 255);
> +    Data.push_back((W >> 40) & 255);
> +    Data.push_back((W >> 48) & 255);
> +    Data.push_back((W >> 56) & 255);
>   }
>
>   /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
>   /// written to the data stream in big-endian format.
>   inline void emitDWordBE(uint64_t W) {
> -    Data.push_back(unsigned(W >> 56) & 255);
> -    Data.push_back(unsigned(W >> 48) & 255);
> -    Data.push_back(unsigned(W >> 40) & 255);
> -    Data.push_back(unsigned(W >> 32) & 255);
> -    Data.push_back(unsigned(W >> 24) & 255);
> -    Data.push_back(unsigned(W >> 16) & 255);
> -    Data.push_back(unsigned(W >>  8) & 255);
> -    Data.push_back(unsigned(W >>  0) & 255);
> +    Data.push_back((W >> 56) & 255);
> +    Data.push_back((W >> 48) & 255);
> +    Data.push_back((W >> 40) & 255);
> +    Data.push_back((W >> 32) & 255);
> +    Data.push_back((W >> 24) & 255);
> +    Data.push_back((W >> 16) & 255);
> +    Data.push_back((W >>  8) & 255);
> +    Data.push_back((W >>  0) & 255);
>   }
>
>   /// fixByte - This callback is invoked when a byte needs to be
> @@ -270,11 +270,11 @@
>   }
>
>   /// emitAlignment - Pad the data to the specified alignment.
> -  void emitAlignment(unsigned Alignment) {
> +  void emitAlignment(unsigned Alignment, uint8_t fill = 0) {
>     if (Alignment <= 1) return;
>     unsigned PadSize = -Data.size() & (Alignment-1);
>     for (unsigned i = 0; i<PadSize; ++i)
> -      Data.push_back(0);
> +      Data.push_back(fill);
>   }
>
>   /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
>
> Modified: llvm/trunk/include/llvm/CodeGen/FileWriters.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FileWriters.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/FileWriters.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/FileWriters.h Mon Jul  6 00:09:34 2009
> @@ -17,14 +17,14 @@
>  namespace llvm {
>
>   class PassManagerBase;
> -  class MachineCodeEmitter;
> +  class ObjectCodeEmitter;
>   class TargetMachine;
>   class raw_ostream;
>
> -  MachineCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O,
> -                                   TargetMachine &TM);
> -  MachineCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O,
> -                                     TargetMachine &TM);
> +  ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O,
> +                                  TargetMachine &TM);
> +  ObjectCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O,
> +                                    TargetMachine &TM);
>
>  } // end llvm namespace
>
>
> Modified: llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h Mon Jul  6 00:09:34 2009
> @@ -74,24 +74,6 @@
>   /// false.
>   ///
>   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.
> -  ///
> -  virtual void startGVStub(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.
> -  ///
> -  virtual void startGVStub(const GlobalValue* GV, void *Buffer,
> -                           unsigned StubSize) = 0;
> -
> -  /// finishGVStub - This callback is invoked to terminate a GV stub.
> -  ///
> -  virtual void *finishGVStub(const GlobalValue* F) = 0;
>
>   /// emitByte - This callback is invoked when a byte needs to be written to the
>   /// output stream.
> @@ -288,14 +270,13 @@
>
>   /// getCurrentPCOffset - Return the offset from the start of the emitted
>   /// buffer that we are currently writing to.
> -  uintptr_t getCurrentPCOffset() const {
> +  virtual uintptr_t getCurrentPCOffset() const {
>     return CurBufferPtr-BufferBegin;
>   }
>
>   /// addRelocation - Whenever a relocatable address is needed, it should be
>   /// noted with this interface.
>   virtual void addRelocation(const MachineRelocation &MR) = 0;
> -
>
>   /// FIXME: These should all be handled with relocations!
>
>
> Modified: llvm/trunk/include/llvm/Target/TargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetMachine.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetMachine.h Mon Jul  6 00:09:34 2009
> @@ -29,6 +29,7 @@
>  class TargetFrameInfo;
>  class MachineCodeEmitter;
>  class JITCodeEmitter;
> +class ObjectCodeEmitter;
>  class TargetRegisterInfo;
>  class Module;
>  class PassManagerBase;
> @@ -257,6 +258,16 @@
>     return true;
>   }
>
> +  /// addPassesToEmitFileFinish - If the passes to emit the specified file had
> +  /// to be split up (e.g., to add an object writer pass), this method can be
> +  /// used to finish up adding passes to emit the file, if necessary.
> +  ///
> +  virtual bool addPassesToEmitFileFinish(PassManagerBase &,
> +                                         ObjectCodeEmitter *,
> +                                         CodeGenOpt::Level) {
> +    return true;
> +  }
> +
>   /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
>   /// get machine code emitted.  This uses a MachineCodeEmitter object to handle
>   /// actually outputting the machine code and resolving things like the address
> @@ -335,7 +346,15 @@
>   /// used to finish up adding passes to emit the file, if necessary.
>   ///
>   virtual bool addPassesToEmitFileFinish(PassManagerBase &PM,
> -                                         JITCodeEmitter *MCE,
> +                                         JITCodeEmitter *JCE,
> +                                         CodeGenOpt::Level);
> +
> +  /// addPassesToEmitFileFinish - If the passes to emit the specified file had
> +  /// to be split up (e.g., to add an object writer pass), this method can be
> +  /// used to finish up adding passes to emit the file, if necessary.
> +  ///
> +  virtual bool addPassesToEmitFileFinish(PassManagerBase &PM,
> +                                         ObjectCodeEmitter *OCE,
>                                          CodeGenOpt::Level);
>
>   /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
> @@ -432,6 +451,15 @@
>     return true;
>   }
>
> +  /// addSimpleCodeEmitter - This pass should be overridden by the target to add
> +  /// a code emitter (without setting flags), if supported.  If this is not
> +  /// supported, 'true' should be returned.  If DumpAsm is true, the generated
> +  /// assembly is printed to cerr.
> +  virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
> +                                    bool /*DumpAsm*/, ObjectCodeEmitter &) {
> +    return true;
> +  }
> +
>   /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
>   /// on this target.  User flag overrides.
>   virtual bool getEnableTailMergeDefault() const { return true; }
>
> Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Mon Jul  6 00:09:34 2009
> @@ -40,6 +40,8 @@
>  #include "llvm/CodeGen/BinaryObject.h"
>  #include "llvm/CodeGen/FileWriters.h"
>  #include "llvm/CodeGen/MachineCodeEmitter.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
> +#include "llvm/CodeGen/MachineCodeEmitter.h"
>  #include "llvm/CodeGen/MachineConstantPool.h"
>  #include "llvm/Target/TargetAsmInfo.h"
>  #include "llvm/Target/TargetData.h"
> @@ -54,12 +56,12 @@
>  char ELFWriter::ID = 0;
>  /// AddELFWriter - Concrete function to add the ELF writer to the function pass
>  /// manager.
> -MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
> +ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
>                                        raw_ostream &O,
>                                        TargetMachine &TM) {
>   ELFWriter *EW = new ELFWriter(O, TM);
>   PM.add(EW);
> -  return &EW->getMachineCodeEmitter();
> +  return (ObjectCodeEmitter*) &EW->getMachineCodeEmitter();
>  }
>
>  //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Jul  6 00:09:34 2009
> @@ -126,6 +126,23 @@
>   return false; // success!
>  }
>
> +/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
> +/// be split up (e.g., to add an object writer pass), this method can be used to
> +/// finish up adding passes to emit the file, if necessary.
> +bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
> +                                                  ObjectCodeEmitter *OCE,
> +                                                  CodeGenOpt::Level OptLevel) {
> +  if (OCE)
> +    addSimpleCodeEmitter(PM, OptLevel, PrintEmittedAsm, *OCE);
> +
> +  PM.add(createGCInfoDeleter());
> +
> +  // Delete machine code for this function
> +  PM.add(createMachineCodeDeleter());
> +
> +  return false; // success!
> +}
> +
>  /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
>  /// get machine code emitted.  This uses a MachineCodeEmitter object to handle
>  /// actually outputting the machine code and resolving things like the address
>
> Modified: llvm/trunk/lib/CodeGen/MachO.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachO.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachO.h (original)
> +++ llvm/trunk/lib/CodeGen/MachO.h Mon Jul  6 00:09:34 2009
> @@ -17,6 +17,7 @@
>  #include "llvm/Constants.h"
>  #include "llvm/DerivedTypes.h"
>  #include "llvm/CodeGen/MachineRelocation.h"
> +#include "llvm/CodeGen/BinaryObject.h"
>  #include "llvm/Target/TargetAsmInfo.h"
>  #include <string>
>  #include <vector>
> @@ -272,11 +273,10 @@
>  /// turned into the SectionCommand in the load command for a particlar
>  /// segment.
>
> -struct MachOSection {
> +struct MachOSection : public BinaryObject {
>   std::string  sectname; // name of this section,
>   std::string  segname;  // segment this section goes in
>   uint64_t  addr;        // memory address of this section
> -  uint64_t  size;        // size in bytes of this section
>   uint32_t  offset;      // file offset of this section
>   uint32_t  align;       // section alignment (power of 2)
>   uint32_t  reloff;      // file offset of relocation entries
> @@ -290,19 +290,10 @@
>   /// to the correct section.
>   uint32_t Index;
>
> -  /// SectionData - The actual data for this section which we are building
> -  /// up for emission to the file.
> -  DataBuffer SectionData;
> -
>   /// RelocBuffer - A buffer to hold the mach-o relocations before we write
>   /// them out at the appropriate location in the file.
>   DataBuffer RelocBuffer;
>
> -  /// Relocations - The relocations that we have encountered so far in this
> -  /// section that we will need to convert to MachORelocation entries when
> -  /// the file is written.
> -  std::vector<MachineRelocation> Relocations;
> -
>   // Constants for the section types (low 8 bits of flags field)
>   // see <mach-o/loader.h>
>   enum { S_REGULAR = 0,
> @@ -374,48 +365,49 @@
>   }
>
>   MachOSection(const std::string &seg, const std::string &sect)
> -    : sectname(sect), segname(seg), addr(0), size(0), offset(0), align(2),
> -      reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
> +    : BinaryObject(), sectname(sect), segname(seg), addr(0), offset(0),
> +      align(2), reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
>       reserved3(0) { }
>
>  }; // end struct MachOSection
>
> -    /// MachOSymTab - This struct contains information about the offsets and
> -    /// size of symbol table information.
> -    /// segment.
> -    struct MachODySymTab {
> -      uint32_t cmd;             // LC_DYSYMTAB
> -      uint32_t cmdsize;         // sizeof( MachODySymTab )
> -      uint32_t ilocalsym;       // index to local symbols
> -      uint32_t nlocalsym;       // number of local symbols
> -      uint32_t iextdefsym;      // index to externally defined symbols
> -      uint32_t nextdefsym;      // number of externally defined symbols
> -      uint32_t iundefsym;       // index to undefined symbols
> -      uint32_t nundefsym;       // number of undefined symbols
> -      uint32_t tocoff;          // file offset to table of contents
> -      uint32_t ntoc;            // number of entries in table of contents
> -      uint32_t modtaboff;       // file offset to module table
> -      uint32_t nmodtab;         // number of module table entries
> -      uint32_t extrefsymoff;    // offset to referenced symbol table
> -      uint32_t nextrefsyms;     // number of referenced symbol table entries
> -      uint32_t indirectsymoff;  // file offset to the indirect symbol table
> -      uint32_t nindirectsyms;   // number of indirect symbol table entries
> -      uint32_t extreloff;       // offset to external relocation entries
> -      uint32_t nextrel;         // number of external relocation entries
> -      uint32_t locreloff;       // offset to local relocation entries
> -      uint32_t nlocrel;         // number of local relocation entries
> -
> -      // Constants for the cmd field
> -      // see <mach-o/loader.h>
> -      enum { LC_DYSYMTAB = 0x0B  // dynamic link-edit symbol table info
> -      };
> -
> -      MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
> -        ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
> -        iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
> -        nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
> -        nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { }
> -    };
> +/// MachOSymTab - This struct contains information about the offsets and
> +/// size of symbol table information.
> +/// segment.
> +struct MachODySymTab {
> +  uint32_t cmd;             // LC_DYSYMTAB
> +  uint32_t cmdsize;         // sizeof(MachODySymTab)
> +  uint32_t ilocalsym;       // index to local symbols
> +  uint32_t nlocalsym;       // number of local symbols
> +  uint32_t iextdefsym;      // index to externally defined symbols
> +  uint32_t nextdefsym;      // number of externally defined symbols
> +  uint32_t iundefsym;       // index to undefined symbols
> +  uint32_t nundefsym;       // number of undefined symbols
> +  uint32_t tocoff;          // file offset to table of contents
> +  uint32_t ntoc;            // number of entries in table of contents
> +  uint32_t modtaboff;       // file offset to module table
> +  uint32_t nmodtab;         // number of module table entries
> +  uint32_t extrefsymoff;    // offset to referenced symbol table
> +  uint32_t nextrefsyms;     // number of referenced symbol table entries
> +  uint32_t indirectsymoff;  // file offset to the indirect symbol table
> +  uint32_t nindirectsyms;   // number of indirect symbol table entries
> +  uint32_t extreloff;       // offset to external relocation entries
> +  uint32_t nextrel;         // number of external relocation entries
> +  uint32_t locreloff;       // offset to local relocation entries
> +  uint32_t nlocrel;         // number of local relocation entries
> +
> +  // Constants for the cmd field
> +  // see <mach-o/loader.h>
> +  enum { LC_DYSYMTAB = 0x0B  // dynamic link-edit symbol table info
> +  };
> +
> +  MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
> +    ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
> +    iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
> +    nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
> +    nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { }
> +
> +}; // end struct MachODySymTab
>
>  } // end namespace llvm
>
>
> Modified: llvm/trunk/lib/CodeGen/MachOCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOCodeEmitter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachOCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachOCodeEmitter.cpp Mon Jul  6 00:09:34 2009
> @@ -16,6 +16,7 @@
>  #include "llvm/Target/TargetAsmInfo.h"
>  #include "llvm/Support/Mangler.h"
>  #include "llvm/Support/OutputBuffer.h"
> +#include <vector>
>
>  //===----------------------------------------------------------------------===//
>  //                       MachOCodeEmitter Implementation
> @@ -39,28 +40,18 @@
>   // Get the Mach-O Section that this function belongs in.
>   MachOSection *MOS = MOW.getTextSection();
>
> -  // FIXME: better memory management
> -  MOS->SectionData.reserve(4096);
> -  BufferBegin = &MOS->SectionData[0];
> -  BufferEnd = BufferBegin + MOS->SectionData.capacity();
> -
>   // Upgrade the section alignment if required.
>   if (MOS->align < Align) MOS->align = Align;
>
> -  // Round the size up to the correct alignment for starting the new function.
> -  if ((MOS->size & ((1 << Align) - 1)) != 0) {
> -    MOS->size += (1 << Align);
> -    MOS->size &= ~((1 << Align) - 1);
> -  }
> +  MOS->emitAlignment(Align);
>
> -  // FIXME: Using MOS->size directly here instead of calculating it from the
> -  // output buffer size (impossible because the code emitter deals only in raw
> -  // bytes) forces us to manually synchronize size and write padding zero bytes
> -  // to the output buffer for all non-text sections.  For text sections, we do
> -  // not synchonize the output buffer, and we just blow up if anyone tries to
> -  // write non-code to it.  An assert should probably be added to
> -  // AddSymbolToSection to prevent calling it on the text section.
> -  CurBufferPtr = BufferBegin + MOS->size;
> +  // Create symbol for function entry
> +  const GlobalValue *FuncV = MF.getFunction();
> +  MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI);
> +  FnSym.n_value = getCurrentPCOffset();
> +
> +  // add it to the symtab.
> +  MOW.SymbolTable.push_back(FnSym);
>  }
>
>  /// finishFunction - This callback is invoked after the function is completely
> @@ -71,15 +62,6 @@
>   // Get the Mach-O Section that this function belongs in.
>   MachOSection *MOS = MOW.getTextSection();
>
> -  // Get a symbol for the function to add to the symbol table
> -  // FIXME: it seems like we should call something like AddSymbolToSection
> -  // in startFunction rather than changing the section size and symbol n_value
> -  // here.
> -  const GlobalValue *FuncV = MF.getFunction();
> -  MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI);
> -  FnSym.n_value = MOS->size;
> -  MOS->size = CurBufferPtr - BufferBegin;
> -
>   // Emit constant pool to appropriate section(s)
>   emitConstantPool(MF.getConstantPool());
>
> @@ -112,12 +94,9 @@
>     } else {
>       assert(0 && "Unhandled relocation type");
>     }
> -    MOS->Relocations.push_back(MR);
> +    MOS->addRelocation(MR);
>   }
>   Relocations.clear();
> -
> -  // Finally, add it to the symtab.
> -  MOW.SymbolTable.push_back(FnSym);
>
>   // Clear per-function data structures.
>   CPLocations.clear();
> @@ -151,13 +130,10 @@
>     unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
>
>     MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
> -    OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
> +    OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
>
> -    CPLocations.push_back(Sec->SectionData.size());
> +    CPLocations.push_back(Sec->size());
>     CPSections.push_back(Sec->Index);
> -
> -    // FIXME: remove when we have unified size + output buffer
> -    Sec->size += Size;
>
>     // Allocate space in the section for the global.
>     // FIXME: need alignment?
> @@ -165,14 +141,12 @@
>     for (unsigned j = 0; j < Size; ++j)
>       SecDataOut.outbyte(0);
>
> -    MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i],
> -                TM.getTargetData(), Sec->Relocations);
> +    MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i], TM.getTargetData(), Sec);
>   }
>  }
>
>  /// emitJumpTables - Emit all the jump tables for a given jump table info
>  /// record to the appropriate section.
> -
>  void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
>   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
>   if (JT.empty()) return;
> @@ -183,24 +157,21 @@
>
>   MachOSection *Sec = MOW.getJumpTableSection();
>   unsigned TextSecIndex = MOW.getTextSection()->Index;
> -  OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
> +  OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
>
>   for (unsigned i = 0, e = JT.size(); i != e; ++i) {
>     // For each jump table, record its offset from the start of the section,
>     // reserve space for the relocations to the MBBs, and add the relocations.
>     const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
> -    JTLocations.push_back(Sec->SectionData.size());
> +    JTLocations.push_back(Sec->size());
>     for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
> -      MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(),
> -                                               MBBs[mi]));
> +      MachineRelocation MR(MOW.GetJTRelocation(Sec->size(), MBBs[mi]));
>       MR.setResultPointer((void *)JTLocations[i]);
>       MR.setConstantVal(TextSecIndex);
> -      Sec->Relocations.push_back(MR);
> +      Sec->addRelocation(MR);
>       SecDataOut.outaddr(0);
>     }
>   }
> -  // FIXME: remove when we have unified size + output buffer
> -  Sec->size = Sec->SectionData.size();
>  }
>
>  } // end namespace llvm
>
> Modified: llvm/trunk/lib/CodeGen/MachOCodeEmitter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOCodeEmitter.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachOCodeEmitter.h (original)
> +++ llvm/trunk/lib/CodeGen/MachOCodeEmitter.h Mon Jul  6 00:09:34 2009
> @@ -11,15 +11,13 @@
>  #define MACHOCODEEMITTER_H
>
>  #include "MachOWriter.h"
> -#include "llvm/CodeGen/MachineCodeEmitter.h"
> -#include <vector>
>
>  namespace llvm {
>
>  /// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
>  /// for functions to the Mach-O file.
>
> -class MachOCodeEmitter : public MachineCodeEmitter {
> +class MachOCodeEmitter : public ObjectCodeEmitter {
>   MachOWriter &MOW;
>
>   /// Target machine description.
> @@ -34,27 +32,12 @@
>   /// Relocations - These are the relocations that the function needs, as
>   /// emitted.
>   std::vector<MachineRelocation> Relocations;
> -
> -  /// CPLocations - This is a map of constant pool indices to offsets from the
> -  /// start of the section for that constant pool index.
> -  std::vector<uintptr_t> CPLocations;
> -
> -  /// CPSections - This is a map of constant pool indices to the MachOSection
> -  /// containing the constant pool entry for that index.
> -  std::vector<unsigned> CPSections;
> -
> -  /// JTLocations - This is a map of jump table indices to offsets from the
> -  /// start of the section for that jump table index.
> -  std::vector<uintptr_t> JTLocations;
> -
> -  /// MBBLocations - This vector is a mapping from MBB ID's to their address.
> -  /// It is filled in by the StartMachineBasicBlock callback and queried by
> -  /// the getMachineBasicBlockAddress callback.
> -  std::vector<uintptr_t> MBBLocations;
> -
> +
> +  std::map<uint64_t, uintptr_t> Labels;
> +
>  public:
> -  MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM)
> -  {
> +  MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
> +        ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
>     is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
>     isLittleEndian = TM.getTargetData()->isLittleEndian();
>     TAI = TM.getTargetAsmInfo();
> @@ -69,58 +52,17 @@
>
>   void emitConstantPool(MachineConstantPool *MCP);
>   void emitJumpTables(MachineJumpTableInfo *MJTI);
> -
> -  virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
> -    assert(CPLocations.size() > Index && "CP not emitted!");
> -    return CPLocations[Index];
> -  }
> -  virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
> -    assert(JTLocations.size() > Index && "JT not emitted!");
> -    return JTLocations[Index];
> -  }
> -
> -  virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
> -    if (MBBLocations.size() <= (unsigned)MBB->getNumber())
> -      MBBLocations.resize((MBB->getNumber()+1)*2);
> -    MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
> -  }
>
> -  virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
> -    assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
> -           MBBLocations[MBB->getNumber()] && "MBB not emitted!");
> -    return MBBLocations[MBB->getNumber()];
> +  virtual void emitLabel(uint64_t LabelID) {
> +    Labels[LabelID] = getCurrentPCOffset();
>   }
>
>   virtual uintptr_t getLabelAddress(uint64_t Label) const {
> -    assert(0 && "get Label not implemented");
> -    abort();
> -    return 0;
> -  }
> -
> -  virtual void emitLabel(uint64_t LabelID) {
> -    assert(0 && "emit Label not implemented");
> -    abort();
> +    return Labels.find(Label)->second;
>   }
>
>   virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
>
> -  /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
> -  virtual void startGVStub(const GlobalValue* F, unsigned StubSize,
> -                           unsigned Alignment = 1) {
> -    assert(0 && "JIT specific function called!");
> -    abort();
> -  }
> -  virtual void startGVStub(const GlobalValue* F, void *Buffer,
> -                           unsigned StubSize) {
> -    assert(0 && "JIT specific function called!");
> -    abort();
> -  }
> -  virtual void *finishGVStub(const GlobalValue* F) {
> -    assert(0 && "JIT specific function called!");
> -    abort();
> -    return 0;
> -  }
> -
>  }; // end class MachOCodeEmitter
>
>  } // end namespace llvm
>
> Modified: llvm/trunk/lib/CodeGen/MachOWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachOWriter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachOWriter.cpp Mon Jul  6 00:09:34 2009
> @@ -46,12 +46,12 @@
>
>  /// AddMachOWriter - Concrete function to add the Mach-O writer to the function
>  /// pass manager.
> -MachineCodeEmitter *AddMachOWriter(PassManagerBase &PM,
> +ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM,
>                                          raw_ostream &O,
>                                          TargetMachine &TM) {
>   MachOWriter *MOW = new MachOWriter(O, TM);
>   PM.add(MOW);
> -  return &MOW->getMachineCodeEmitter();
> +  return MOW->getObjectCodeEmitter();
>  }
>
>  //===----------------------------------------------------------------------===//
> @@ -60,8 +60,9 @@
>
>  char MachOWriter::ID = 0;
>
> -MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
> -  : MachineFunctionPass(&ID), O(o), TM(tm) {
> +MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
> +  : MachineFunctionPass(&ID), O(o), TM(tm)
> +  {
>   is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
>   isLittleEndian = TM.getTargetData()->isLittleEndian();
>
> @@ -69,11 +70,11 @@
>
>   // Create the machine code emitter object for this target.
>
> -  MCE = new MachOCodeEmitter(*this);
> +  MachOCE = new MachOCodeEmitter(*this, *getTextSection(true));
>  }
>
>  MachOWriter::~MachOWriter() {
> -  delete MCE;
> +  delete MachOCE;
>  }
>
>  bool MachOWriter::doInitialization(Module &M) {
> @@ -97,13 +98,13 @@
>  /// the Mach-O file to 'O'.
>  bool MachOWriter::doFinalization(Module &M) {
>   // FIXME: we don't handle debug info yet, we should probably do that.
> -
> -  // Okay, the.text section has been completed, build the .data, .bss, and
> +  // Okay, the.text section has been completed, build the .data, .bss, and
>   // "common" sections next.
> +
>   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
>        I != E; ++I)
>     EmitGlobal(I);
> -
> +
>   // Emit the header and load commands.
>   EmitHeaderAndLoadCommands();
>
> @@ -133,38 +134,32 @@
>   // Reserve space in the .bss section for this symbol while maintaining the
>   // desired section alignment, which must be at least as much as required by
>   // this symbol.
> -  OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
> +  OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
>
>   if (Align) {
> -    uint64_t OrigSize = Sec->size;
>     Align = Log2_32(Align);
>     Sec->align = std::max(unsigned(Sec->align), Align);
> -    Sec->size = (Sec->size + Align - 1) & ~(Align-1);
>
> -    // Add alignment padding to buffer as well.
> -    // FIXME: remove when we have unified size + output buffer
> -    unsigned AlignedSize = Sec->size - OrigSize;
> -    for (unsigned i = 0; i < AlignedSize; ++i)
> -      SecDataOut.outbyte(0);
> +    Sec->emitAlignment(Sec->align);
>   }
>   // Globals without external linkage apparently do not go in the symbol table.
>   if (!GV->hasLocalLinkage()) {
>     MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TAI);
> -    Sym.n_value = Sec->size;
> +    Sym.n_value = Sec->size();
>     SymbolTable.push_back(Sym);
>   }
>
>   // Record the offset of the symbol, and then allocate space for it.
>   // FIXME: remove when we have unified size + output buffer
> -  Sec->size += Size;
> -
> -  // Now that we know what section the GlovalVariable is going to be emitted
> +
> +  // Now that we know what section the GlovalVariable is going to be emitted
>   // into, update our mappings.
>   // FIXME: We may also need to update this when outputting non-GlobalVariable
>   // GlobalValues such as functions.
> -  GVSection[GV] = Sec;
> -  GVOffset[GV] = Sec->SectionData.size();
>
> +  GVSection[GV] = Sec;
> +  GVOffset[GV] = Sec->size();
> +
>   // Allocate space in the section for the global.
>   for (unsigned i = 0; i < Size; ++i)
>     SecDataOut.outbyte(0);
> @@ -174,7 +169,7 @@
>   const Type *Ty = GV->getType()->getElementType();
>   unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
>   bool NoInit = !GV->hasInitializer();
> -
> +
>   // If this global has a zero initializer, it is part of the .bss or common
>   // section.
>   if (NoInit || GV->getInitializer()->isNullValue()) {
> @@ -183,8 +178,7 @@
>     // merged with other symbols.
>     if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
>         GV->hasCommonLinkage()) {
> -      MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV),
> -                              MachOSym::NO_SECT, TAI);
> +      MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT, TAI);
>       // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
>       // bytes of the symbol.
>       ExtOrCommonSym.n_value = Size;
> @@ -198,15 +192,14 @@
>     AddSymbolToSection(BSS, GV);
>     return;
>   }
> -
> +
>   // Scalar read-only data goes in a literal section if the scalar is 4, 8, or
>   // 16 bytes, or a cstring.  Other read only data goes into a regular const
>   // section.  Read-write data goes in the data section.
> -  MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
> +  MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
>                                          getDataSection();
>   AddSymbolToSection(Sec, GV);
> -  InitMem(GV->getInitializer(), &Sec->SectionData[0], GVOffset[GV],
> -          TM.getTargetData(), Sec->Relocations);
> +  InitMem(GV->getInitializer(), GVOffset[GV], TM.getTargetData(), Sec);
>  }
>
>
> @@ -214,21 +207,22 @@
>  void MachOWriter::EmitHeaderAndLoadCommands() {
>   // Step #0: Fill in the segment load command size, since we need it to figure
>   //          out the rest of the header fields
> +
>   MachOSegment SEG("", is64Bit);
>   SEG.nsects  = SectionList.size();
> -  SEG.cmdsize = SEG.cmdSize(is64Bit) +
> +  SEG.cmdsize = SEG.cmdSize(is64Bit) +
>                 SEG.nsects * SectionList[0]->cmdSize(is64Bit);
> -
> +
>   // Step #1: calculate the number of load commands.  We always have at least
>   //          one, for the LC_SEGMENT load command, plus two for the normal
>   //          and dynamic symbol tables, if there are any symbols.
>   Header.ncmds = SymbolTable.empty() ? 1 : 3;
> -
> +
>   // Step #2: calculate the size of the load commands
>   Header.sizeofcmds = SEG.cmdsize;
>   if (!SymbolTable.empty())
>     Header.sizeofcmds += SymTab.cmdsize + DySymTab.cmdsize;
> -
> +
>   // Step #3: write the header to the file
>   // Local alias to shortenify coming code.
>   DataBuffer &FH = Header.HeaderData;
> @@ -243,15 +237,15 @@
>   FHOut.outword(Header.flags);
>   if (is64Bit)
>     FHOut.outword(Header.reserved);
> -
> +
>   // Step #4: Finish filling in the segment load command and write it out
>   for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
>          E = SectionList.end(); I != E; ++I)
> -    SEG.filesize += (*I)->size;
> +    SEG.filesize += (*I)->size();
>
>   SEG.vmsize = SEG.filesize;
>   SEG.fileoff = Header.cmdSize(is64Bit) + Header.sizeofcmds;
> -
> +
>   FHOut.outword(SEG.cmd);
>   FHOut.outword(SEG.cmdsize);
>   FHOut.outstring(SEG.segname, 16);
> @@ -263,42 +257,42 @@
>   FHOut.outword(SEG.initprot);
>   FHOut.outword(SEG.nsects);
>   FHOut.outword(SEG.flags);
> -
> -  // Step #5: Finish filling in the fields of the MachOSections
> +
> +  // Step #5: Finish filling in the fields of the MachOSections
>   uint64_t currentAddr = 0;
>   for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
>          E = SectionList.end(); I != E; ++I) {
>     MachOSection *MOS = *I;
>     MOS->addr = currentAddr;
>     MOS->offset = currentAddr + SEG.fileoff;
> -
>     // FIXME: do we need to do something with alignment here?
> -    currentAddr += MOS->size;
> +    currentAddr += MOS->size();
>   }
> -
> +
>   // Step #6: Emit the symbol table to temporary buffers, so that we know the
>   // size of the string table when we write the next load command.  This also
>   // sorts and assigns indices to each of the symbols, which is necessary for
>   // emitting relocations to externally-defined objects.
>   BufferSymbolAndStringTable();
> -
> +
>   // Step #7: Calculate the number of relocations for each section and write out
>   // the section commands for each section
>   currentAddr += SEG.fileoff;
>   for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
>          E = SectionList.end(); I != E; ++I) {
>     MachOSection *MOS = *I;
> +
>     // Convert the relocations to target-specific relocations, and fill in the
>     // relocation offset for this section.
>     CalculateRelocations(*MOS);
>     MOS->reloff = MOS->nreloc ? currentAddr : 0;
>     currentAddr += MOS->nreloc * 8;
> -
> +
>     // write the finalized section command to the output buffer
>     FHOut.outstring(MOS->sectname, 16);
>     FHOut.outstring(MOS->segname, 16);
>     FHOut.outaddr(MOS->addr);
> -    FHOut.outaddr(MOS->size);
> +    FHOut.outaddr(MOS->size());
>     FHOut.outword(MOS->offset);
>     FHOut.outword(MOS->align);
>     FHOut.outword(MOS->reloff);
> @@ -309,7 +303,7 @@
>     if (is64Bit)
>       FHOut.outword(MOS->reserved3);
>   }
> -
> +
>   // Step #8: Emit LC_SYMTAB/LC_DYSYMTAB load commands
>   SymTab.symoff  = currentAddr;
>   SymTab.nsyms   = SymbolTable.size();
> @@ -345,39 +339,40 @@
>   FHOut.outword(DySymTab.nextrel);
>   FHOut.outword(DySymTab.locreloff);
>   FHOut.outword(DySymTab.nlocrel);
> -
> +
>   O.write((char*)&FH[0], FH.size());
>  }
>
>  /// EmitSections - Now that we have constructed the file header and load
>  /// commands, emit the data for each section to the file.
> -
>  void MachOWriter::EmitSections() {
>   for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
>          E = SectionList.end(); I != E; ++I)
>     // Emit the contents of each section
> -    O.write((char*)&(*I)->SectionData[0], (*I)->size);
> +    if ((*I)->size())
> +      O.write((char*)&(*I)->getData()[0], (*I)->size());
>  }
> +
> +/// EmitRelocations - emit relocation data from buffer.
>  void MachOWriter::EmitRelocations() {
>   for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
>          E = SectionList.end(); I != E; ++I)
>     // Emit the relocation entry data for each section.
> -    O.write((char*)&(*I)->RelocBuffer[0], (*I)->RelocBuffer.size());
> +    if ((*I)->RelocBuffer.size())
> +      O.write((char*)&(*I)->RelocBuffer[0], (*I)->RelocBuffer.size());
>  }
>
>  /// BufferSymbolAndStringTable - Sort the symbols we encountered and assign them
>  /// each a string table index so that they appear in the correct order in the
>  /// output file.
> -
>  void MachOWriter::BufferSymbolAndStringTable() {
>   // The order of the symbol table is:
>   // 1. local symbols
>   // 2. defined external symbols (sorted by name)
>   // 3. undefined external symbols (sorted by name)
> -
> +
>   // Before sorting the symbols, check the PendingGlobals for any undefined
>   // globals that need to be put in the symbol table.
> -
>   for (std::vector<GlobalValue*>::iterator I = PendingGlobals.begin(),
>          E = PendingGlobals.end(); I != E; ++I) {
>     if (GVOffset[*I] == 0 && GVSection[*I] == 0) {
> @@ -389,19 +384,15 @@
>
>   // Sort the symbols by name, so that when we partition the symbols by scope
>   // of definition, we won't have to sort by name within each partition.
> -
>   std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSym::SymCmp());
>
> -  // Parition the symbol table entries so that all local symbols come before
> +  // Parition the symbol table entries so that all local symbols come before
>   // all symbols with external linkage. { 1 | 2 3 }
> -
> -  std::partition(SymbolTable.begin(), SymbolTable.end(),
> -                 MachOSym::PartitionByLocal);
> -
> +  std::partition(SymbolTable.begin(), SymbolTable.end(), MachOSym::PartitionByLocal);
> +
>   // Advance iterator to beginning of external symbols and partition so that
>   // all external symbols defined in this module come before all external
>   // symbols defined elsewhere. { 1 | 2 | 3 }
> -
>   for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
>          E = SymbolTable.end(); I != E; ++I) {
>     if (!MachOSym::PartitionByLocal(*I)) {
> @@ -410,10 +401,9 @@
>     }
>   }
>
> -  // Calculate the starting index for each of the local, extern defined, and
> +  // Calculate the starting index for each of the local, extern defined, and
>   // undefined symbols, as well as the number of each to put in the LC_DYSYMTAB
>   // load command.
> -
>   for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
>          E = SymbolTable.end(); I != E; ++I) {
>     if (MachOSym::PartitionByLocal(*I)) {
> @@ -427,10 +417,9 @@
>       ++DySymTab.nundefsym;
>     }
>   }
> -
> +
>   // Write out a leading zero byte when emitting string table, for n_strx == 0
>   // which means an empty string.
> -
>   OutputBuffer StrTOut(StrT, is64Bit, isLittleEndian);
>   StrTOut.outbyte(0);
>
> @@ -439,7 +428,6 @@
>   // 2. strings for local symbols
>   // Since this is the opposite order from the symbol table, which we have just
>   // sorted, we can walk the symbol table backwards to output the string table.
> -
>   for (std::vector<MachOSym>::reverse_iterator I = SymbolTable.rbegin(),
>         E = SymbolTable.rend(); I != E; ++I) {
>     if (I->GVName == "") {
> @@ -463,7 +451,7 @@
>       I->n_value += GVSection[GV]->addr;
>     if (GV && (GVOffset[GV] == -1))
>       GVOffset[GV] = index;
> -
> +
>     // Emit nlist to buffer
>     SymTOut.outword(I->n_strx);
>     SymTOut.outbyte(I->n_type);
> @@ -478,32 +466,29 @@
>  /// and the offset into that section.  From this information, create the
>  /// appropriate target-specific MachORelocation type and add buffer it to be
>  /// written out after we are finished writing out sections.
> -
>  void MachOWriter::CalculateRelocations(MachOSection &MOS) {
> -  for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) {
> -    MachineRelocation &MR = MOS.Relocations[i];
> +  std::vector<MachineRelocation> Relocations =  MOS.getRelocations();
> +  for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
> +    MachineRelocation &MR = Relocations[i];
>     unsigned TargetSection = MR.getConstantVal();
>     unsigned TargetAddr = 0;
>     unsigned TargetIndex = 0;
>
>     // This is a scattered relocation entry if it points to a global value with
>     // a non-zero offset.
> -
>     bool Scattered = false;
>     bool Extern = false;
>
>     // Since we may not have seen the GlobalValue we were interested in yet at
>     // the time we emitted the relocation for it, fix it up now so that it
>     // points to the offset into the correct section.
> -
>     if (MR.isGlobalValue()) {
>       GlobalValue *GV = MR.getGlobalValue();
>       MachOSection *MOSPtr = GVSection[GV];
>       intptr_t Offset = GVOffset[GV];
> -
> +
>       // If we have never seen the global before, it must be to a symbol
>       // defined in another module (N_UNDF).
> -
>       if (!MOSPtr) {
>         // FIXME: need to append stub suffix
>         Extern = true;
> @@ -515,10 +500,9 @@
>       }
>       MR.setResultPointer((void*)Offset);
>     }
> -
> +
>     // If the symbol is locally defined, pass in the address of the section and
>     // the section index to the code which will generate the target relocation.
> -
>     if (!Extern) {
>         MachOSection &To = *SectionList[TargetSection - 1];
>         TargetAddr = To.addr;
> @@ -526,7 +510,7 @@
>     }
>
>     OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian);
> -    OutputBuffer SecOut(MOS.SectionData, is64Bit, isLittleEndian);
> +    OutputBuffer SecOut(MOS.getData(), is64Bit, isLittleEndian);
>
>     MOS.nreloc += GetTargetRelocation(MR, MOS.Index, TargetAddr, TargetIndex,
>                                       RelocOut, SecOut, Scattered, Extern);
> @@ -535,22 +519,21 @@
>
>  // InitMem - Write the value of a Constant to the specified memory location,
>  // converting it into bytes and relocations.
> -
> -void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
> -                          const TargetData *TD,
> -                          std::vector<MachineRelocation> &MRs) {
> +void MachOWriter::InitMem(const Constant *C, uintptr_t Offset,
> +                          const TargetData *TD, MachOSection* mos) {
>   typedef std::pair<const Constant*, intptr_t> CPair;
>   std::vector<CPair> WorkList;
> -
> +  uint8_t *Addr = &mos->getData()[0];
> +
>   WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
> -
> +
>   intptr_t ScatteredOffset = 0;
> -
> +
>   while (!WorkList.empty()) {
>     const Constant *PC = WorkList.back().first;
>     intptr_t PA = WorkList.back().second;
>     WorkList.pop_back();
> -
> +
>     if (isa<UndefValue>(PC)) {
>       continue;
>     } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
> @@ -643,7 +626,7 @@
>           memset(ptr, 0, TD->getPointerSize());
>         else if (const GlobalValue* GV = dyn_cast<GlobalValue>(PC)) {
>           // FIXME: what about function stubs?
> -          MRs.push_back(MachineRelocation::getGV(PA-(intptr_t)Addr,
> +          mos->addRelocation(MachineRelocation::getGV(PA-(intptr_t)Addr,
>                                                  MachineRelocation::VANILLA,
>                                                  const_cast<GlobalValue*>(GV),
>                                                  ScatteredOffset));
>
> Modified: llvm/trunk/lib/CodeGen/MachOWriter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/MachOWriter.h (original)
> +++ llvm/trunk/lib/CodeGen/MachOWriter.h Mon Jul  6 00:09:34 2009
> @@ -15,17 +15,24 @@
>  #define MACHOWRITER_H
>
>  #include "MachO.h"
> +#include "llvm/Constants.h"
> +#include "llvm/DerivedTypes.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/Target/TargetData.h"
>  #include "llvm/Target/TargetMachine.h"
>  #include "llvm/Target/TargetMachOWriterInfo.h"
> +#include <vector>
>  #include <map>
>
>  namespace llvm {
>   class GlobalVariable;
>   class Mangler;
> -  class MachineCodeEmitter;
> +  class MachineRelocation;
> +  class ObjectCodeEmitter;
>   class MachOCodeEmitter;
> +  class TargetData;
> +  class TargetMachine;
>   class OutputBuffer;
>   class raw_ostream;
>
> @@ -38,8 +45,9 @@
>     friend class MachOCodeEmitter;
>   public:
>     static char ID;
> -    MachineCodeEmitter &getMachineCodeEmitter() const {
> -      return *(MachineCodeEmitter*)MCE;
> +
> +    ObjectCodeEmitter *getObjectCodeEmitter() {
> +      return reinterpret_cast<ObjectCodeEmitter*>(MachOCE);
>     }
>
>     MachOWriter(raw_ostream &O, TargetMachine &TM);
> @@ -62,10 +70,10 @@
>     ///
>     Mangler *Mang;
>
> -    /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
> +    /// MachOCE - The MachineCodeEmitter object that we are exposing to emit machine
>     /// code for functions to the .o file.
>
> -    MachOCodeEmitter *MCE;
> +    MachOCodeEmitter *MachOCE;
>
>     /// is64Bit/isLittleEndian - This information is inferred from the target
>     /// machine directly, indicating what header values and flags to set.
> @@ -225,9 +233,10 @@
>     /// SymbolTable to aid in emitting the DYSYMTAB load command.
>     std::vector<unsigned> DynamicSymbolTable;
>
> -    static void InitMem(const Constant *C, void *Addr, intptr_t Offset,
> +    static void InitMem(const Constant *C,
> +                        uintptr_t Offset,
>                         const TargetData *TD,
> -                        std::vector<MachineRelocation> &MRs);
> +                        MachOSection* mos);
>
>   private:
>     void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
>
> Modified: llvm/trunk/lib/Target/ARM/ARM.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARM.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARM.h Mon Jul  6 00:09:34 2009
> @@ -24,6 +24,7 @@
>  class FunctionPass;
>  class MachineCodeEmitter;
>  class JITCodeEmitter;
> +class ObjectCodeEmitter;
>  class raw_ostream;
>
>  // Enums corresponding to ARM condition codes
> @@ -101,6 +102,8 @@
>                                        MachineCodeEmitter &MCE);
>  FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
>                                           JITCodeEmitter &JCE);
> +FunctionPass *createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM,
> +                                             ObjectCodeEmitter &OCE);
>
>  FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false);
>  FunctionPass *createARMConstantIslandPass();
>
> Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Jul  6 00:09:34 2009
> @@ -26,6 +26,7 @@
>  #include "llvm/PassManager.h"
>  #include "llvm/CodeGen/MachineCodeEmitter.h"
>  #include "llvm/CodeGen/JITCodeEmitter.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/CodeGen/MachineConstantPool.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
>  #include "llvm/CodeGen/MachineInstr.h"
> @@ -174,18 +175,18 @@
>  /// createARMCodeEmitterPass - Return a pass that emits the collected ARM code
>  /// to the specified MCE object.
>
> -namespace llvm {
> -
> -FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
> -                                       MachineCodeEmitter &MCE) {
> +FunctionPass *llvm::createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
> +                                             MachineCodeEmitter &MCE) {
>   return new Emitter<MachineCodeEmitter>(TM, MCE);
>  }
> -FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
> -                                          JITCodeEmitter &JCE) {
> +FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
> +                                                JITCodeEmitter &JCE) {
>   return new Emitter<JITCodeEmitter>(TM, JCE);
>  }
> -
> -} // end namespace llvm
> +FunctionPass *llvm::createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM,
> +                                                   ObjectCodeEmitter &OCE) {
> +  return new Emitter<ObjectCodeEmitter>(TM, OCE);
> +}
>
>  template<class CodeEmitter>
>  bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
>
> Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Mon Jul  6 00:09:34 2009
> @@ -228,6 +228,25 @@
>   return false;
>  }
>
> +bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
> +                                          CodeGenOpt::Level OptLevel,
> +                                          bool DumpAsm,
> +                                          ObjectCodeEmitter &OCE) {
> +  // FIXME: Move this to TargetJITInfo!
> +  if (DefRelocModel == Reloc::Default)
> +    setRelocationModel(Reloc::Static);
> +
> +  // Machine code emitter pass for ARM.
> +  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
> +
>  bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
>                                                 CodeGenOpt::Level OptLevel,
>                                                 bool DumpAsm,
> @@ -258,4 +277,18 @@
>   return false;
>  }
>
> +bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
> +                                            CodeGenOpt::Level OptLevel,
> +                                            bool DumpAsm,
> +                                            ObjectCodeEmitter &OCE) {
> +  // Machine code emitter pass for ARM.
> +  PM.add(createARMObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.h Mon Jul  6 00:09:34 2009
> @@ -77,6 +77,8 @@
>                               bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
>                               bool DumpAsm, JITCodeEmitter &MCE);
> +  virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
> +                              bool DumpAsm, ObjectCodeEmitter &OCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm,
> @@ -85,6 +87,10 @@
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm,
>                                     JITCodeEmitter &MCE);
> +  virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
> +                                    CodeGenOpt::Level OptLevel,
> +                                    bool DumpAsm,
> +                                    ObjectCodeEmitter &OCE);
>  };
>
>  /// ARMTargetMachine - ARM target machine.
>
> Modified: llvm/trunk/lib/Target/Alpha/Alpha.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/Alpha.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Alpha/Alpha.h (original)
> +++ llvm/trunk/lib/Target/Alpha/Alpha.h Mon Jul  6 00:09:34 2009
> @@ -22,6 +22,7 @@
>   class AlphaTargetMachine;
>   class FunctionPass;
>   class MachineCodeEmitter;
> +  class ObjectCodeEmitter;
>   class raw_ostream;
>
>   FunctionPass *createAlphaISelDag(AlphaTargetMachine &TM);
> @@ -32,7 +33,9 @@
>   FunctionPass *createAlphaCodeEmitterPass(AlphaTargetMachine &TM,
>                                            MachineCodeEmitter &MCE);
>   FunctionPass *createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM,
> -                                           JITCodeEmitter &JCE);
> +                                              JITCodeEmitter &JCE);
> +  FunctionPass *createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM,
> +                                                 ObjectCodeEmitter &OCE);
>   FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm);
>   FunctionPass *createAlphaBranchSelectionPass();
>
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaCodeEmitter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaCodeEmitter.cpp Mon Jul  6 00:09:34 2009
> @@ -19,6 +19,7 @@
>  #include "llvm/PassManager.h"
>  #include "llvm/CodeGen/MachineCodeEmitter.h"
>  #include "llvm/CodeGen/JITCodeEmitter.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
>  #include "llvm/CodeGen/MachineInstr.h"
>  #include "llvm/CodeGen/Passes.h"
> @@ -91,6 +92,10 @@
>                                                   JITCodeEmitter &JCE) {
>   return new Emitter<JITCodeEmitter>(TM, JCE);
>  }
> +FunctionPass *llvm::createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM,
> +                                                     ObjectCodeEmitter &OCE) {
> +  return new Emitter<ObjectCodeEmitter>(TM, OCE);
> +}
>
>  template <class CodeEmitter>
>  bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.cpp Mon Jul  6 00:09:34 2009
> @@ -119,6 +119,17 @@
>   }
>   return false;
>  }
> +bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
> +                                        CodeGenOpt::Level OptLevel,
> +                                        bool DumpAsm, ObjectCodeEmitter &OCE) {
> +  PM.add(createAlphaObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +  return false;
> +}
>  bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
>                                               CodeGenOpt::Level OptLevel,
>                                               bool DumpAsm,
> @@ -131,4 +142,10 @@
>                                               JITCodeEmitter &JCE) {
>   return addCodeEmitter(PM, OptLevel, DumpAsm, JCE);
>  }
> +bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
> +                                              CodeGenOpt::Level OptLevel,
> +                                              bool DumpAsm,
> +                                              ObjectCodeEmitter &OCE) {
> +  return addCodeEmitter(PM, OptLevel, DumpAsm, OCE);
> +}
>
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.h (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaTargetMachine.h Mon Jul  6 00:09:34 2009
> @@ -74,6 +74,8 @@
>                               bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
>                               bool DumpAsm, JITCodeEmitter &JCE);
> +  virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
> +                              bool DumpAsm, ObjectCodeEmitter &JCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm,
> @@ -82,6 +84,10 @@
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm,
>                                     JITCodeEmitter &JCE);
> +  virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
> +                                    CodeGenOpt::Level OptLevel,
> +                                    bool DumpAsm,
> +                                    ObjectCodeEmitter &OCE);
>
>   static void registerAsmPrinter(AsmPrinterCtorFn F) {
>     AsmPrinterCtor = F;
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPC.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPC.h (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPC.h Mon Jul  6 00:09:34 2009
> @@ -24,6 +24,7 @@
>   class PPCTargetMachine;
>   class FunctionPass;
>   class MachineCodeEmitter;
> +  class ObjectCodeEmitter;
>   class raw_ostream;
>
>  FunctionPass *createPPCBranchSelectionPass();
> @@ -33,7 +34,9 @@
>  FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
>                                        MachineCodeEmitter &MCE);
>  FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
> -                                       JITCodeEmitter &MCE);
> +                                          JITCodeEmitter &MCE);
> +FunctionPass *createPPCObjectCodeEmitterPass(PPCTargetMachine &TM,
> +                                             ObjectCodeEmitter &OCE);
>  } // end namespace llvm;
>
>  // Defines symbolic names for PowerPC registers.  This defines a mapping from
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp Mon Jul  6 00:09:34 2009
> @@ -19,6 +19,7 @@
>  #include "llvm/PassManager.h"
>  #include "llvm/CodeGen/MachineCodeEmitter.h"
>  #include "llvm/CodeGen/JITCodeEmitter.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
>  #include "llvm/CodeGen/MachineInstrBuilder.h"
>  #include "llvm/CodeGen/MachineModuleInfo.h"
> @@ -91,6 +92,7 @@
>
>  /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
>  /// to the specified MCE object.
> +
>  FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM,
>                                              MachineCodeEmitter &MCE) {
>   return new Emitter<MachineCodeEmitter>(TM, MCE);
> @@ -101,6 +103,11 @@
>   return new Emitter<JITCodeEmitter>(TM, JCE);
>  }
>
> +FunctionPass *llvm::createPPCObjectCodeEmitterPass(PPCTargetMachine &TM,
> +                                                   ObjectCodeEmitter &OCE) {
> +  return new Emitter<ObjectCodeEmitter>(TM, OCE);
> +}
> +
>  template <class CodeEmitter>
>  bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
>   assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
> @@ -252,6 +259,7 @@
>       Reloc = PPC::reloc_pcrel_bx;
>     else // BCC instruction
>       Reloc = PPC::reloc_pcrel_bcx;
> +
>     MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
>                                                Reloc, MO.getMBB()));
>   } else {
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp Mon Jul  6 00:09:34 2009
> @@ -221,6 +221,38 @@
>   return false;
>  }
>
> +bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
> +                                      CodeGenOpt::Level OptLevel,
> +                                      bool DumpAsm, ObjectCodeEmitter &OCE) {
> +  // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
> +  // FIXME: This should be moved to TargetJITInfo!!
> +  if (Subtarget.isPPC64()) {
> +    // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many
> +    // instructions to materialize arbitrary global variable + function +
> +    // constant pool addresses.
> +    setRelocationModel(Reloc::PIC_);
> +    // Temporary workaround for the inability of PPC64 JIT to handle jump
> +    // tables.
> +    DisableJumpTables = true;
> +  } else {
> +    setRelocationModel(Reloc::Static);
> +  }
> +
> +  // Inform the subtarget that we are in JIT mode.  FIXME: does this break macho
> +  // writing?
> +  Subtarget.SetJITMode();
> +
> +  // Machine code emitter pass for PowerPC.
> +  PM.add(createPPCObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
> +
>  bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
>                                             CodeGenOpt::Level OptLevel,
>                                             bool DumpAsm,
> @@ -251,3 +283,19 @@
>   return false;
>  }
>
> +bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
> +                                            CodeGenOpt::Level OptLevel,
> +                                            bool DumpAsm,
> +                                            ObjectCodeEmitter &OCE) {
> +  // Machine code emitter pass for PowerPC.
> +  PM.add(createPPCObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
> +
> +
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h Mon Jul  6 00:09:34 2009
> @@ -85,12 +85,17 @@
>                               bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
>                               bool DumpAsm, JITCodeEmitter &JCE);
> +  virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
> +                              bool DumpAsm, ObjectCodeEmitter &OCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm, JITCodeEmitter &JCE);
> +  virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
> +                                    CodeGenOpt::Level OptLevel,
> +                                    bool DumpAsm, ObjectCodeEmitter &OCE);
>   virtual bool getEnableTailMergeDefault() const;
>  };
>
>
> Modified: llvm/trunk/lib/Target/X86/X86.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86.h (original)
> +++ llvm/trunk/lib/Target/X86/X86.h Mon Jul  6 00:09:34 2009
> @@ -56,6 +56,8 @@
>                                        MachineCodeEmitter &MCE);
>  FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
>                                           JITCodeEmitter &JCE);
> +FunctionPass *createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
> +                                             ObjectCodeEmitter &OCE);
>
>  /// createX86EmitCodeToMemory - Returns a pass that converts a register
>  /// allocated function into raw machine code in a dynamically
>
> Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Mon Jul  6 00:09:34 2009
> @@ -22,6 +22,7 @@
>  #include "llvm/PassManager.h"
>  #include "llvm/CodeGen/MachineCodeEmitter.h"
>  #include "llvm/CodeGen/JITCodeEmitter.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/CodeGen/MachineFunctionPass.h"
>  #include "llvm/CodeGen/MachineInstr.h"
>  #include "llvm/CodeGen/MachineModuleInfo.h"
> @@ -106,18 +107,18 @@
>  /// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
>  /// to the specified templated MachineCodeEmitter object.
>
> -namespace llvm {
> -
> -FunctionPass *createX86CodeEmitterPass(X86TargetMachine &TM,
> -                                       MachineCodeEmitter &MCE) {
> +FunctionPass *llvm::createX86CodeEmitterPass(X86TargetMachine &TM,
> +                                             MachineCodeEmitter &MCE) {
>   return new Emitter<MachineCodeEmitter>(TM, MCE);
>  }
> -FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
> -                                          JITCodeEmitter &JCE) {
> +FunctionPass *llvm::createX86JITCodeEmitterPass(X86TargetMachine &TM,
> +                                                JITCodeEmitter &JCE) {
>   return new Emitter<JITCodeEmitter>(TM, JCE);
>  }
> -
> -} // end namespace llvm
> +FunctionPass *llvm::createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
> +                                                   ObjectCodeEmitter &OCE) {
> +  return new Emitter<ObjectCodeEmitter>(TM, OCE);
> +}
>
>  template<class CodeEmitter>
>  bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
>
> Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Mon Jul  6 00:09:34 2009
> @@ -290,6 +290,36 @@
>   return false;
>  }
>
> +bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM,
> +                                      CodeGenOpt::Level OptLevel,
> +                                      bool DumpAsm,
> +                                      ObjectCodeEmitter &OCE) {
> +  // FIXME: Move this to TargetJITInfo!
> +  // On Darwin, do not override 64-bit setting made in X86TargetMachine().
> +  if (DefRelocModel == Reloc::Default &&
> +        (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit()))
> +    setRelocationModel(Reloc::Static);
> +
> +  // 64-bit JIT places everything in the same buffer except external functions.
> +  // On Darwin, use small code model but hack the call instruction for
> +  // externals.  Elsewhere, do not assume globals are in the lower 4G.
> +  if (Subtarget.is64Bit()) {
> +    if (Subtarget.isTargetDarwin())
> +      setCodeModel(CodeModel::Small);
> +    else
> +      setCodeModel(CodeModel::Large);
> +  }
> +
> +  PM.add(createX86ObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
> +
>  bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
>                                             CodeGenOpt::Level OptLevel,
>                                             bool DumpAsm,
> @@ -318,3 +348,16 @@
>   return false;
>  }
>
> +bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
> +                                            CodeGenOpt::Level OptLevel,
> +                                            bool DumpAsm,
> +                                            ObjectCodeEmitter &OCE) {
> +  PM.add(createX86ObjectCodeEmitterPass(*this, OCE));
> +  if (DumpAsm) {
> +    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
> +    if (AsmPrinterCtor)
> +      PM.add(AsmPrinterCtor(errs(), *this, true));
> +  }
> +
> +  return false;
> +}
>
> Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.h?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86TargetMachine.h (original)
> +++ llvm/trunk/lib/Target/X86/X86TargetMachine.h Mon Jul  6 00:09:34 2009
> @@ -84,12 +84,17 @@
>                               bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
>                               bool DumpAsm, JITCodeEmitter &JCE);
> +  virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
> +                              bool DumpAsm, ObjectCodeEmitter &OCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm, MachineCodeEmitter &MCE);
>   virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
>                                     CodeGenOpt::Level OptLevel,
>                                     bool DumpAsm, JITCodeEmitter &JCE);
> +  virtual bool addSimpleCodeEmitter(PassManagerBase &PM,
> +                                    CodeGenOpt::Level OptLevel,
> +                                    bool DumpAsm, ObjectCodeEmitter &OCE);
>  };
>
>  /// X86_32TargetMachine - X86 32-bit target machine.
>
> Modified: llvm/trunk/tools/llc/llc.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llc/llc.cpp (original)
> +++ llvm/trunk/tools/llc/llc.cpp Mon Jul  6 00:09:34 2009
> @@ -17,6 +17,7 @@
>  #include "llvm/CodeGen/FileWriters.h"
>  #include "llvm/CodeGen/LinkAllCodegenComponents.h"
>  #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
> +#include "llvm/CodeGen/ObjectCodeEmitter.h"
>  #include "llvm/Target/SubtargetFeature.h"
>  #include "llvm/Target/TargetData.h"
>  #include "llvm/Target/TargetMachine.h"
> @@ -312,7 +313,7 @@
>  #endif
>
>     // Ask the target to add backend passes as necessary.
> -    MachineCodeEmitter *MCE = 0;
> +    ObjectCodeEmitter *OCE = 0;
>
>     // Override default to generate verbose assembly.
>     Target.setAsmVerbosityDefault(true);
> @@ -331,14 +332,14 @@
>     case FileModel::AsmFile:
>       break;
>     case FileModel::MachOFile:
> -      MCE = AddMachOWriter(Passes, *Out, Target);
> +      OCE = AddMachOWriter(Passes, *Out, Target);
>       break;
>     case FileModel::ElfFile:
> -      MCE = AddELFWriter(Passes, *Out, Target);
> +      OCE = AddELFWriter(Passes, *Out, Target);
>       break;
>     }
>
> -    if (Target.addPassesToEmitFileFinish(Passes, MCE, OLvl)) {
> +    if (Target.addPassesToEmitFileFinish(Passes, OCE, OLvl)) {
>       std::cerr << argv[0] << ": target does not support generation of this"
>                 << " file type!\n";
>       if (Out != &outs()) delete Out;
>
> Modified: llvm/trunk/tools/lto/LTOCodeGenerator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOCodeGenerator.cpp?rev=74813&r1=74812&r2=74813&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lto/LTOCodeGenerator.cpp (original)
> +++ llvm/trunk/tools/lto/LTOCodeGenerator.cpp Mon Jul  6 00:09:34 2009
> @@ -430,16 +430,16 @@
>
>     codeGenPasses->add(new TargetData(*_target->getTargetData()));
>
> -    MachineCodeEmitter* mce = NULL;
> +    ObjectCodeEmitter* oce = NULL;
>
>     switch (_target->addPassesToEmitFile(*codeGenPasses, out,
>                                          TargetMachine::AssemblyFile,
>                                          CodeGenOpt::Aggressive)) {
>         case FileModel::MachOFile:
> -            mce = AddMachOWriter(*codeGenPasses, out, *_target);
> +            oce = AddMachOWriter(*codeGenPasses, out, *_target);
>             break;
>         case FileModel::ElfFile:
> -            mce = AddELFWriter(*codeGenPasses, out, *_target);
> +            oce = AddELFWriter(*codeGenPasses, out, *_target);
>             break;
>         case FileModel::AsmFile:
>             break;
> @@ -449,7 +449,7 @@
>             return true;
>     }
>
> -    if (_target->addPassesToEmitFileFinish(*codeGenPasses, mce,
> +    if (_target->addPassesToEmitFileFinish(*codeGenPasses, oce,
>                                            CodeGenOpt::Aggressive)) {
>         errMsg = "target does not support generation of this file type";
>         return true;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Bruno Cardoso Lopes
http://www.brunocardoso.cc
-------------- next part --------------
This MachO-DOE patch introduces the ObjectCodeEmitter and BinaryObject classes 
and adds ObejectCodeEmitter to the code emitters, intermediate and llc, and
LTO code. This demonstrates and tests the ObjectCodeEmitter and BinaryObject 
classes, but stubs the ELFWritter and makes it useless until updated to use 
this prototype DOE framework.

I added label support to the MachOWriter in the process and am getting semi 
encoraging results in its output.

 * include/llvm/Target/TargetMachine.h

   class TargetMachine

     - added addPassesToEmitFileFinish() for ObjectCodeEmitter

   class LLVMTargetMachine

     - addPassesToEmitFileFinish() for ObjectCodeEmitter
     - addSimpleCodeEmitter() for ObjectCodeEmitter

 * include/llvm/CodeGen/FileWriters.h

     - change AddMachOWriter() to return an ObjectCodeEmitter
     - change AddELFWriter() to return an ObjectCodeEmitter

 * include/llvm/CodeGen/MachineCodeEmitter.h

   - removed GVStub methods
   - made MachineCodeEmitter::getCurrentPCOffset() virtual

 * include/llvm/CodeGen/ObjectCodeEmitter.h

   - new file

 * include/llvm/CodeGen/BinaryObject.h

  - removed unnecessary unsigned casts
  - added reserveBytes() method
  - added Alignment filler byte value

 * lib/CodeGen/LLVMTargetMachine.cpp

   - added LLVMTargetMachine::addPassesToEmitFileFinish()

 * lib/CodeGen/ELFWriter.cpp

   - kludge to cast and converted AddELFWriter to return ObjectCodeEmitter

 * lib/CodeGen/MachO.h
 * lib/CodeGen/MachOCodeEmitter.h
 * lib/CodeGen/MachOCodeEmitter.cpp
 * lib/CodeGen/MachOWriter.h
 * lib/CodeGen/MachOWriter.cpp

  - converted to use ObjectCodeEmitter
  - made getObjectCodeEmitter() return a pointer

 * lib/Target/X86/X86.h
 * lib/Target/X86/X86CodeEmitter.cpp

   - added createX86ObjectCodeEmitterPass()

 * lib/Target/X86/X86TargetMachine.h
 * lib/Target/X86/X86TargetMachine.cpp

   - added X86TargetMachine::addCodeEmitter()
   - added X86TargetMachine::addSimpleCodeEmitter()

 * lib/Target/PowerPC/PPC.h
 * lib/Target/PowerPC/PPCCodeEmitter.cpp

   - added createPPCObjectCodeEmitterPass()

 * lib/Target/PowerPC/PPCTargetMachine.h
 * lib/Target/PowerPC/PPCTargetMachine.cpp

  - added PPCTargetMachine::addCodeEmitter()
  - added PPCTargetMachine::addSimpleCodeEmitter()
 
 * lib/Target/ARM/ARM.h
 * lib/Target/ARM/ARMCodeEmitter.cpp

  - added createARMObjectCodeEmitterPass()

 * lib/Target/ARM/ARMTargetMachine.h
 * lib/Target/ARM/ARMTargetMachine.cpp

  - added ARMTargetMachine::addCodeEmitter()
  - added ARMTargetMachine::addSimpleCodeEmitter()

 * lib/Target/Alpha/Alpha.h
 * lib/Target/Alpha/AlphaCodeEmitter.cpp

  - added createAlphaObjectCodeEmitterPass()

 * lib/Target/Alpha/AlphaTargetMachine.h
 * lib/Target/Alpha/AlphaTargetMachine.cpp

  - added AlphaTargetMachine::addCodeEmitter()
  - added AlphaTargetMachine::addSimpleCodeEmitter()

 * tools/lto/LTOCodeGenerator.cpp
 * tools/llc/llc.cpp

  - converted to use ObjectCodeEmitter



More information about the llvm-commits mailing list