Add hook in MCSection to decide when to use "optimized nops", for each
section kind. Previously, optimized nops were only used for MachO.
Also added tests for ELF and COFF.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115523 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 5c99735..3e5b5f1 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -61,6 +61,10 @@
       return false;
     }
 
+    // UseCodeAlign - Return true if a .align directive should use
+    // "optimized nops" to fill instead of 0s.
+    virtual bool UseCodeAlign() const = 0;
+
     static bool classof(const MCSection *) { return true; }
   };
 
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index f828e10..62d07cf 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -55,6 +55,7 @@
     
     virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
                                       raw_ostream &OS) const;
+    virtual bool UseCodeAlign() const;
 
     static bool classof(const MCSection *S) {
       return S->getVariant() == SV_COFF;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index f97ab16..a92d0f2 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -178,7 +178,8 @@
   
   void PrintSwitchToSection(const MCAsmInfo &MAI,
                             raw_ostream &OS) const;
-  
+  virtual bool UseCodeAlign() const;
+
   /// isBaseAddressKnownZero - We know that non-allocatable sections (like
   /// debug info) have a base of zero.
   virtual bool isBaseAddressKnownZero() const {
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 2d9d133..19d003a 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -165,6 +165,7 @@
 
   virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
                                     raw_ostream &OS) const;
+  virtual bool UseCodeAlign() const;
 
   static bool classof(const MCSection *S) {
     return S->getVariant() == SV_MachO;
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index fbac34a..688827d 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -1654,12 +1654,7 @@
 
   // Check whether we should use optimal code alignment for this .align
   // directive.
-  //
-  // FIXME: This should be using a target hook.
-  bool UseCodeAlign = false;
-  if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
-        getStreamer().getCurrentSection()))
-    UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
+  bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign();
   if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
       ValueSize == 1 && UseCodeAlign) {
     getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index eb53160..0909df4 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/lib/MC/MCSectionCOFF.cpp
@@ -74,3 +74,7 @@
     }
   }
 }
+
+bool MCSectionCOFF::UseCodeAlign() const {
+  return getKind().isText();
+}
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
index ef935d0..133cad1 100644
--- a/lib/MC/MCSectionELF.cpp
+++ b/lib/MC/MCSectionELF.cpp
@@ -112,6 +112,10 @@
   OS << '\n';
 }
 
+bool MCSectionELF::UseCodeAlign() const {
+  return getFlags() & MCSectionELF::SHF_EXECINSTR;
+}
+
 // HasCommonSymbols - True if this section holds common symbols, this is
 // indicated on the ELF object file by a symbol with SHN_COMMON section 
 // header index.
diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp
index ded3b20..12b3efe 100644
--- a/lib/MC/MCSectionMachO.cpp
+++ b/lib/MC/MCSectionMachO.cpp
@@ -148,6 +148,10 @@
   OS << '\n';
 }
 
+bool MCSectionMachO::UseCodeAlign() const {
+  return hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
+}
+
 /// StripSpaces - This removes leading and trailing spaces from the StringRef.
 static void StripSpaces(StringRef &Str) {
   while (!Str.empty() && isspace(Str[0]))
@@ -283,4 +287,3 @@
   
   return "";
 }
-
diff --git a/lib/Target/PIC16/PIC16Section.cpp b/lib/Target/PIC16/PIC16Section.cpp
index 2505b11..7664fbb 100644
--- a/lib/Target/PIC16/PIC16Section.cpp
+++ b/lib/Target/PIC16/PIC16Section.cpp
@@ -102,3 +102,7 @@
 
   OS << '\n';
 }
+
+bool PIC16Section::UseCodeAlign() const {
+  return isCODE_Type();
+}
diff --git a/lib/Target/PIC16/PIC16Section.h b/lib/Target/PIC16/PIC16Section.h
index 5b33b51..98e5902 100644
--- a/lib/Target/PIC16/PIC16Section.h
+++ b/lib/Target/PIC16/PIC16Section.h
@@ -88,6 +88,8 @@
     virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
                                       raw_ostream &OS) const;
 
+    virtual bool UseCodeAlign() const;
+
     static bool classof(const MCSection *S) {
       return S->getVariant() == SV_PIC16;
     }
diff --git a/test/MC/COFF/align-nops.s b/test/MC/COFF/align-nops.s
new file mode 100644
index 0000000..f190fdb
--- /dev/null
+++ b/test/MC/COFF/align-nops.s
@@ -0,0 +1,45 @@
+// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s -o %t
+// RUN: coff-dump.py %abs_tmp | FileCheck %s
+        
+// Test that we get optimal nops in text
+    .text
+f0:
+    .long 0
+    .align  8, 0x90
+    .long 0
+    .align  8
+
+// But not in another section
+    .data
+    .long 0
+    .align  8, 0x90
+    .long 0
+    .align  8
+
+//CHECK:         Name                     = .text
+//CHECK-NEXT:    VirtualSize
+//CHECK-NEXT:    VirtualAddress
+//CHECK-NEXT:    SizeOfRawData            = 16
+//CHECK-NEXT:    PointerToRawData
+//CHECK-NEXT:    PointerToRelocations
+//CHECK-NEXT:    PointerToLineNumbers
+//CHECK-NEXT:    NumberOfRelocations
+//CHECK-NEXT:    NumberOfLineNumbers
+//CHECK-NEXT:    Charateristics           = 0x400001
+//CHECK-NEXT:        IMAGE_SCN_ALIGN_8BYTES
+//CHECK-NEXT:      SectionData              = 
+//CHECK-NEXT:        00 00 00 00 0F 1F 40 00 - 00 00 00 00 0F 1F 40 00
+
+//CHECK:         Name                     = .data
+//CHECK-NEXT:      VirtualSize
+//CHECK-NEXT:      VirtualAddress
+//CHECK-NEXT:      SizeOfRawData            = 16
+//CHECK-NEXT:      PointerToRawData
+//CHECK-NEXT:      PointerToRelocations
+//CHECK-NEXT:      PointerToLineNumbers
+//CHECK-NEXT:      NumberOfRelocations
+//CHECK-NEXT:      NumberOfLineNumbers
+//CHECK-NEXT:      Charateristics           = 0x400001
+//CHECK-NEXT:        IMAGE_SCN_ALIGN_8BYTES
+//CHECK-NEXT:      SectionData              = 
+//CHECK-NEXT:        00 00 00 00 90 90 90 90 - 00 00 00 00 00 00 00 00
diff --git a/test/MC/COFF/dg.exp b/test/MC/COFF/dg.exp
index 7b7bd4e..d46d700 100644
--- a/test/MC/COFF/dg.exp
+++ b/test/MC/COFF/dg.exp
@@ -1,5 +1,5 @@
 load_lib llvm.exp
 
 if { [llvm_supports_target X86] } {
-  RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
+  RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,s}]]
 }
diff --git a/test/MC/ELF/align-nops.s b/test/MC/ELF/align-nops.s
new file mode 100644
index 0000000..b6793ec
--- /dev/null
+++ b/test/MC/ELF/align-nops.s
@@ -0,0 +1,40 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
+
+// Test that we get optimal nops in text
+    .text
+f0:
+    .long 0
+    .align  8, 0x90
+    .long 0
+    .align  8
+
+// But not in another section
+    .data
+    .long 0
+    .align  8, 0x90
+    .long 0
+    .align  8
+
+// CHECK: (('sh_name', 1) # '.text'
+// CHECK-NEXT:  ('sh_type', 1)
+// CHECK-NEXT:  ('sh_flags', 6)
+// CHECK-NEXT:  ('sh_addr',
+// CHECK-NEXT:  ('sh_offset',
+// CHECK-NEXT:  ('sh_size', 16)
+// CHECK-NEXT:  ('sh_link', 0)
+// CHECK-NEXT:  ('sh_info', 0)
+// CHECK-NEXT:  ('sh_addralign', 8)
+// CHECK-NEXT:  ('sh_entsize', 0)
+// CHECK-NEXT:  ('_section_data', '00000000 0f1f4000 00000000 0f1f4000')
+
+// CHECK: (('sh_name', 7) # '.data'
+// CHECK-NEXT:  ('sh_type', 1)
+// CHECK-NEXT:  ('sh_flags', 3)
+// CHECK-NEXT:  ('sh_addr',
+// CHECK-NEXT:  ('sh_offset',
+// CHECK-NEXT:  ('sh_size', 16)
+// CHECK-NEXT:  ('sh_link', 0)
+// CHECK-NEXT:  ('sh_info', 0)
+// CHECK-NEXT:  ('sh_addralign', 8)
+// CHECK-NEXT:  ('sh_entsize', 0)
+// CHECK-NEXT:  ('_section_data', '00000000 90909090 00000000 00000000')