[llvm-commits] [llvm] r96963 - in /llvm/trunk: include/llvm/MC/MCAssembler.h include/llvm/MC/MCStreamer.h lib/MC/MCAsmStreamer.cpp lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp lib/MC/MCNullStreamer.cpp

Kevin Enderby enderby at apple.com
Tue Feb 23 10:26:34 PST 2010


Author: enderby
Date: Tue Feb 23 12:26:34 2010
New Revision: 96963

URL: http://llvm.org/viewvc/llvm-project?rev=96963&view=rev
Log:
This is the first patch to put the needed bits in place to eventually allow code
to be aligned with optimal nops.  This patch does not change any functionality
and when the compiler is changed to use EmitCodeAlignment() it should also not
change the resulting output.  Once the compiler change is made and everything
looks good the next patch with the table of optimal X86 nops will be added to
WriteNopData() changing the output.  There are many FIXMEs in this patch which
will be removed when we have better target hooks (coming soon I hear).

Modified:
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/lib/MC/MCNullStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Tue Feb 23 12:26:34 2010
@@ -195,12 +195,16 @@
   /// cannot be satisfied in this width then this fragment is ignored.
   unsigned MaxBytesToEmit;
 
+  /// EmitNops - true when aligning code and optimal nops to be used for filling
+  bool EmitNops;
+
 public:
   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
-                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+                  unsigned _MaxBytesToEmit, bool _EmitNops,
+		  MCSectionData *SD = 0)
     : MCFragment(FT_Align, SD), Alignment(_Alignment),
       Value(_Value),ValueSize(_ValueSize),
-      MaxBytesToEmit(_MaxBytesToEmit) {}
+      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {}
 
   /// @name Accessors
   /// @{
@@ -217,6 +221,8 @@
 
   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
 
+  unsigned getEmitNops() const { return EmitNops; }
+
   /// @}
 
   static bool classof(const MCFragment *F) {

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Feb 23 12:26:34 2010
@@ -232,6 +232,20 @@
                                       unsigned ValueSize = 1,
                                       unsigned MaxBytesToEmit = 0) = 0;
 
+    /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
+    /// is reached.
+    ///
+    /// This used to align code where the alignment bytes may be executed.  This
+    /// can emit different bytes for different sizes to optimize execution.
+    ///
+    /// @param ByteAlignment - The alignment to reach. This must be a power of
+    /// two on some targets.
+    /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+    /// the alignment cannot be reached in this many bytes, no bytes are
+    /// emitted.
+    virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                   unsigned MaxBytesToEmit = 0) = 0;
+
     /// EmitValueToOffset - Emit some number of copies of @p Value until the
     /// byte offset @p Offset is reached.
     ///

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Tue Feb 23 12:26:34 2010
@@ -134,6 +134,9 @@
                                     unsigned ValueSize = 1,
                                     unsigned MaxBytesToEmit = 0);
 
+  virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                 unsigned MaxBytesToEmit = 0);
+
   virtual void EmitValueToOffset(const MCExpr *Offset,
                                  unsigned char Value = 0);
 
@@ -513,6 +516,12 @@
   EmitEOL();
 }
 
+void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+                                      unsigned MaxBytesToEmit) {
+  // FIXME: a hack for now to only work for x86 using the 0x90 nop opcode.
+  EmitValueToAlignment(ByteAlignment, 0x90, 1, MaxBytesToEmit);
+}
+
 void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
                                       unsigned char Value) {
   // FIXME: Verify that Offset is associated with the current section.

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Tue Feb 23 12:26:34 2010
@@ -42,6 +42,8 @@
 static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
                           MachObjectWriter &MOW);
 
+static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW);
+
 /// isVirtualSection - Check if this is a section which does not actually exist
 /// in the object file.
 static bool isVirtualSection(const MCSection &Section) {
@@ -1058,6 +1060,19 @@
     SD.setFileSize(Address - SD.getAddress());
 }
 
+/// WriteNopData - Write optimal nops to the output file for the \arg Count
+/// bytes.  This returns the number of bytes written.  It may return 0 if
+/// the \arg Count is more than the maximum optimal nops.
+///
+/// FIXME this is X86 32-bit specific and should move to a better place.
+static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
+  // FIXME for now just use the 0x90 nop opcode byte.
+  for (uint64_t i = 0; i < Count; i++)
+    MOW.Write8 (uint8_t(0x90));
+
+  return Count;
+}
+
 /// WriteFileData - Write the \arg F data to the output file.
 static void WriteFileData(raw_ostream &OS, const MCFragment &F,
                           MachObjectWriter &MOW) {
@@ -1081,6 +1096,14 @@
                         "' is not a divisor of padding size '" +
                         Twine(AF.getFileSize()) + "'");
 
+    // See if we are aligning with nops, and if so do that first to try to fill
+    // the Count bytes.  Then if that did not fill any bytes or there are any
+    // bytes left to fill use the the Value and ValueSize to fill the rest.
+    if (AF.getEmitNops()) {
+      uint64_t NopByteCount = WriteNopData(Count, MOW);
+      Count -= NopByteCount;
+    }
+
     for (uint64_t i = 0; i != Count; ++i) {
       switch (AF.getValueSize()) {
       default:

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Tue Feb 23 12:26:34 2010
@@ -137,6 +137,8 @@
   virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
                                     unsigned ValueSize = 1,
                                     unsigned MaxBytesToEmit = 0);
+  virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                 unsigned MaxBytesToEmit = 0);
   virtual void EmitValueToOffset(const MCExpr *Offset,
                                  unsigned char Value = 0);
   
@@ -357,7 +359,20 @@
   if (MaxBytesToEmit == 0)
     MaxBytesToEmit = ByteAlignment;
   new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
-                      CurSectionData);
+                      false /* EmitNops */, CurSectionData);
+
+  // Update the maximum alignment on the current section if necessary.
+  if (ByteAlignment > CurSectionData->getAlignment())
+    CurSectionData->setAlignment(ByteAlignment);
+}
+
+void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+                                        unsigned MaxBytesToEmit) {
+  if (MaxBytesToEmit == 0)
+    MaxBytesToEmit = ByteAlignment;
+  // FIXME the 0x90 is the default x86 1 byte nop opcode.
+  new MCAlignFragment(ByteAlignment, 0x90, 1, MaxBytesToEmit,
+                      true /* EmitNops */, CurSectionData);
 
   // Update the maximum alignment on the current section if necessary.
   if (ByteAlignment > CurSectionData->getAlignment())

Modified: llvm/trunk/lib/MC/MCNullStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCNullStreamer.cpp?rev=96963&r1=96962&r2=96963&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCNullStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCNullStreamer.cpp Tue Feb 23 12:26:34 2010
@@ -55,6 +55,9 @@
                                       unsigned ValueSize = 1,
                                       unsigned MaxBytesToEmit = 0) {}
 
+    virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                   unsigned MaxBytesToEmit = 0) {}
+
     virtual void EmitValueToOffset(const MCExpr *Offset,
                                    unsigned char Value = 0) {}
     





More information about the llvm-commits mailing list