Add hook in MCSection to decide when to use "optimized nops", for each
authorJan Wen Voung <jvoung@google.com>
Mon, 4 Oct 2010 17:32:41 +0000 (17:32 +0000)
committerJan Wen Voung <jvoung@google.com>
Mon, 4 Oct 2010 17:32:41 +0000 (17:32 +0000)
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

13 files changed:
include/llvm/MC/MCSection.h
include/llvm/MC/MCSectionCOFF.h
include/llvm/MC/MCSectionELF.h
include/llvm/MC/MCSectionMachO.h
lib/MC/MCParser/AsmParser.cpp
lib/MC/MCSectionCOFF.cpp
lib/MC/MCSectionELF.cpp
lib/MC/MCSectionMachO.cpp
lib/Target/PIC16/PIC16Section.cpp
lib/Target/PIC16/PIC16Section.h
test/MC/COFF/align-nops.s [new file with mode: 0644]
test/MC/COFF/dg.exp
test/MC/ELF/align-nops.s [new file with mode: 0644]

index 5c997357c9d3818db320a29d5940760009a33b57..3e5b5f13f324433e1a506ecc803fcde94557c19a 100644 (file)
@@ -61,6 +61,10 @@ namespace llvm {
       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; }
   };
 
index f828e1060fe62a9c7d59eec74a12fde9eb1737cc..62d07cf4368c99865917a518ebdbbb0fcb561494 100644 (file)
@@ -55,6 +55,7 @@ namespace llvm {
     
     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;
index f97ab1671180e14b7a0fcb0a74ed2190f31394b5..a92d0f2c9507ea5a2c3efb62a51b79383f115c65 100644 (file)
@@ -178,7 +178,8 @@ public:
   
   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 {
index 2d9d1333dbe23a9d917447a397902ac781501780..19d003a3b5a4bd5b77f787c00864ed537708f22d 100644 (file)
@@ -165,6 +165,7 @@ public:
 
   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;
index fbac34a15ea4e5f4ee98eeb3402069d54f78961f..688827d2c76917c0f181e8757aca11e8940b69a7 100644 (file)
@@ -1654,12 +1654,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
 
   // 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);
index eb531600f72736e55259b11bbc3e243eb9fc29ab..0909df42227cf4c260d8081716df07fa06c416c2 100644 (file)
@@ -74,3 +74,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
     }
   }
 }
+
+bool MCSectionCOFF::UseCodeAlign() const {
+  return getKind().isText();
+}
index ef935d0c64bae09de11c862250e0931fdbfef598..133cad1b32cf4c3527611a6cd604f22f539df822 100644 (file)
@@ -112,6 +112,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
   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.
index ded3b20eaf531973d81ad40ec3eac29d03d946c5..12b3efe663f42b92baf8bc92dad94b4d8719beaf 100644 (file)
@@ -148,6 +148,10 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
   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 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec,        // In.
   
   return "";
 }
-
index 2505b111f1e80ac5f83058aaa1807f77f4d1c885..7664fbbb7d40672ce5496390b989759a976a5be7 100644 (file)
@@ -102,3 +102,7 @@ void PIC16Section::PrintSwitchToSection(const MCAsmInfo &MAI,
 
   OS << '\n';
 }
+
+bool PIC16Section::UseCodeAlign() const {
+  return isCODE_Type();
+}
index 5b33b51a386627a4ab27c7806a8d4ea82b19cd8d..98e590229bd6bd4f6999859eebed6d8bc89bf025 100644 (file)
@@ -88,6 +88,8 @@ namespace llvm {
     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 (file)
index 0000000..f190fdb
--- /dev/null
@@ -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
index 7b7bd4e73807cd29cc50e10343a052f9263c3978..d46d700975e5b4eaee15385102bd8331c8013ed9 100644 (file)
@@ -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 (file)
index 0000000..b6793ec
--- /dev/null
@@ -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')