this is (unfortunately) several changes mixed together:
authorChris Lattner <sabre@nondot.org>
Sat, 25 Jul 2009 18:57:34 +0000 (18:57 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 25 Jul 2009 18:57:34 +0000 (18:57 +0000)
1. Spell SectionFlags::Writeable as "Writable".
2. Add predicates for deriving SectionFlags from SectionKinds.
3. Sink ELF-specific getSectionPrefixForUniqueGlobal impl into
   ELFTargetAsmInfo.
4. Fix SectionFlagsForGlobal to know that BSS/ThreadBSS has the
   BSS bit set (the real fix for PR4619).
5. Fix isSuitableForBSS to not put globals with explicit sections
   set in BSS (which was the reason #4 wasn't fixed earlier).
6. Remove my previous hack for PR4619.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77085 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/Target/DarwinTargetAsmInfo.h
include/llvm/Target/ELFTargetAsmInfo.h
include/llvm/Target/TargetAsmInfo.h
lib/CodeGen/ELFWriter.cpp
lib/Target/CellSPU/SPUTargetAsmInfo.cpp
lib/Target/DarwinTargetAsmInfo.cpp
lib/Target/ELFTargetAsmInfo.cpp
lib/Target/PIC16/PIC16AsmPrinter.cpp
lib/Target/PIC16/PIC16TargetAsmInfo.cpp
lib/Target/PowerPC/PPCTargetAsmInfo.cpp
lib/Target/Sparc/SparcTargetAsmInfo.cpp
lib/Target/TargetAsmInfo.cpp
lib/Target/X86/X86TargetAsmInfo.cpp
lib/Target/XCore/XCoreTargetAsmInfo.cpp

index e1662dd869009f83f0e09390ff590caacdb06e97..10faacca7ec9928876e5b43b77943003ae5e8eba 100644 (file)
@@ -43,12 +43,6 @@ namespace llvm {
     virtual const Section *
     getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const;
     
-    virtual const char *
-    getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
-      // Darwin doesn't use uniqued sections for weak symbols.
-      return 0;
-    }
-
   private:
     const Section* MergeableStringSection(const GlobalVariable *GV) const;
   };
index 54220e765fd196ac36749bb61bb31689dddaae2c..5bd9938d97b51e455a3512eb4783ad926f2bea41 100644 (file)
@@ -37,6 +37,8 @@ namespace llvm {
     /// ".tbss" gets the TLS bit set etc.
     virtual unsigned getFlagsForNamedSection(const char *Section) const;
     
+    const char *getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const;
+    
     virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
                                                   SectionKind::Kind Kind) const;
     virtual std::string printSectionFlags(unsigned flags) const;
index 24d54cc00cd575291669bf27c92ce1e486840416..b8851a6eee77abf9adc49234ef9a3dfcc571f9a4 100644 (file)
@@ -62,13 +62,35 @@ namespace llvm {
               K == SectionKind::RODataMergeConst ||
               K == SectionKind::RODataMergeStr);
     }
+
+    static inline bool isBSS(Kind K) {
+      return K == BSS || K == ThreadBSS;
+    }
+    
+    static inline bool isTLS(Kind K) {
+      return K == ThreadData || K == ThreadBSS;
+    }
+    
+    static inline bool isCode(Kind K) {
+      return K == Text;
+    }
+    
+    static inline bool isWritable(Kind K) {
+      return isTLS(K) ||
+             K == SectionKind::Data ||
+             K == SectionKind::DataRel ||
+             K == SectionKind::DataRelLocal ||
+             K == SectionKind::DataRelRO ||
+             K == SectionKind::DataRelROLocal ||
+             K == SectionKind::BSS;
+    }
   }
 
   namespace SectionFlags {
     const unsigned Invalid    = -1U;
     const unsigned None       = 0;
     const unsigned Code       = 1 << 0;  ///< Section contains code
-    const unsigned Writeable  = 1 << 1;  ///< Section is writeable
+    const unsigned Writable   = 1 << 1;  ///< Section is writable
     const unsigned BSS        = 1 << 2;  ///< Section contains only zeroes
     const unsigned Mergeable  = 1 << 3;  ///< Section contains mergeable data
     const unsigned Strings    = 1 << 4;  ///< Section contains C-type strings
@@ -582,7 +604,9 @@ namespace llvm {
     /// global.  This is important for globals that need to be merged across
     /// translation units.
     virtual const char *
-    getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const;
+    getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
+      return 0;
+    }
     
     /// getFlagsForNamedSection - If this target wants to be able to infer
     /// section flags based on the name of the section specified for a global
index 8cbaf6f13bd6ebd651108273441bc41515d5280f..45658e061271681c3d51d260b512f4e4cb98dea1 100644 (file)
@@ -222,7 +222,7 @@ unsigned ELFWriter::getElfSectionFlags(unsigned Flags) {
 
   if (Flags & SectionFlags::Code)
     ElfSectionFlags |= ELFSection::SHF_EXECINSTR;
-  if (Flags & SectionFlags::Writeable)
+  if (Flags & SectionFlags::Writable)
     ElfSectionFlags |= ELFSection::SHF_WRITE;
   if (Flags & SectionFlags::Mergeable)
     ElfSectionFlags |= ELFSection::SHF_MERGE;
index 2868ff7592c24aaf2d569f06e7fd1ea669468396..000ba01c869a44dd3cd286b62f3738ba56e6d9fb 100644 (file)
@@ -36,7 +36,7 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
   // BSS section needs to be emitted as ".section"
   BSSSection = "\t.section\t.bss";
   BSSSection_ = getUnnamedSection("\t.section\t.bss",
-                                  SectionFlags::Writeable | SectionFlags::BSS,
+                                  SectionFlags::Writable | SectionFlags::BSS,
                                   true);
 
   SupportsDebugInformation = true;
index 2d3c5ff34684a1fabf721023c070b5b1995b00f3..2d750a5a82ba8ad1304bc2426a5e7bcc7c29a2d6 100644 (file)
@@ -50,7 +50,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM)
                                          SectionFlags::None);
   ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None);
   DataCoalSection = getNamedSection("\t__DATA,__datacoal_nt,coalesced",
-                                    SectionFlags::Writeable);
+                                    SectionFlags::Writable);
     
   
   // Common settings for all Darwin targets.
@@ -127,6 +127,7 @@ bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV,
 const Section*
 DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
                                             SectionKind::Kind Kind) const {
+  // FIXME: Use sectionflags:linkonce instead of isWeakForLinker() here.
   bool isWeak = GV->isWeakForLinker();
   bool isNonStatic = TM.getRelocationModel() != Reloc::Static;
 
index 9dd339ed0a299ed3c1991ca886e31f69a7fc3173..ea0783621168ac6423f7604ace2e6d5d4d69a97b 100644 (file)
@@ -29,20 +29,20 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
   : TargetAsmInfo(TM) {
 
   BSSSection_  = getUnnamedSection("\t.bss",
-                                   SectionFlags::Writeable | SectionFlags::BSS);
+                                   SectionFlags::Writable | SectionFlags::BSS);
   ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None);
   TLSDataSection = getNamedSection("\t.tdata",
-                                   SectionFlags::Writeable | SectionFlags::TLS);
+                                   SectionFlags::Writable | SectionFlags::TLS);
   TLSBSSSection = getNamedSection("\t.tbss",
-                SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS);
+                SectionFlags::Writable | SectionFlags::TLS | SectionFlags::BSS);
 
-  DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writeable);
+  DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writable);
   DataRelLocalSection = getNamedSection("\t.data.rel.local",
-                                        SectionFlags::Writeable);
+                                        SectionFlags::Writable);
   DataRelROSection = getNamedSection("\t.data.rel.ro",
-                                     SectionFlags::Writeable);
+                                     SectionFlags::Writable);
   DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local",
-                                          SectionFlags::Writeable);
+                                          SectionFlags::Writable);
 }
 
 
@@ -145,6 +145,28 @@ unsigned ELFTargetAsmInfo::getFlagsForNamedSection(const char *Name) const {
 }
 
 
+
+const char *
+ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const{
+  switch (Kind) {
+  default: llvm_unreachable("Unknown section kind");
+  case SectionKind::Text:             return ".gnu.linkonce.t.";
+  case SectionKind::Data:             return ".gnu.linkonce.d.";
+  case SectionKind::DataRel:          return ".gnu.linkonce.d.rel.";
+  case SectionKind::DataRelLocal:     return ".gnu.linkonce.d.rel.local.";
+  case SectionKind::DataRelRO:        return ".gnu.linkonce.d.rel.ro.";
+  case SectionKind::DataRelROLocal:   return ".gnu.linkonce.d.rel.ro.local.";
+  case SectionKind::BSS:              return ".gnu.linkonce.b.";
+  case SectionKind::ROData:
+  case SectionKind::RODataMergeConst:
+  case SectionKind::RODataMergeStr:   return ".gnu.linkonce.r.";
+  case SectionKind::ThreadData:       return ".gnu.linkonce.td.";
+  case SectionKind::ThreadBSS:        return ".gnu.linkonce.tb.";
+  }
+}
+
+
+
 const Section*
 ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
   const TargetData *TD = TM.getTargetData();
@@ -177,7 +199,7 @@ std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
     Flags += 'a';
   if (flags & SectionFlags::Code)
     Flags += 'x';
-  if (flags & SectionFlags::Writeable)
+  if (flags & SectionFlags::Writable)
     Flags += 'w';
   if (flags & SectionFlags::Mergeable)
     Flags += 'M';
index 95d363e4ecc1754f6c47bfc5c6f8532fe263a6ee..7195551e4c7a12096c3449fd2e9beeefcef03656 100644 (file)
@@ -292,7 +292,7 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
   const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str();
 
   const Section *fPDataSection = TAI->getNamedSection(SectionName,
-                                                      SectionFlags::Writeable);
+                                                      SectionFlags::Writable);
   SwitchToSection(fPDataSection);
   
   // Emit function frame label
index 6f4b0c5c8d859bd7a389059611bd46f703cf97dc..dce1b7876936ab39962c7edd33797aae386bfebf 100644 (file)
@@ -38,9 +38,9 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
   AsciiDirective = " dt ";
   AscizDirective = NULL;
   BSSSection_  = getNamedSection("udata.# UDATA",
-                              SectionFlags::Writeable | SectionFlags::BSS);
+                              SectionFlags::Writable | SectionFlags::BSS);
   ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None);
-  DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
+  DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writable);
   SwitchToSectionDirective = "";
   // Need because otherwise a .text symbol is emitted by DwarfWriter
   // in BeginModule, and gpasm cribbs for that .text symbol.
index ebffd693d64421b8109d3c5456c4110716e0efa2..0a5530e0dbdcd935dd08e1bf265e47bc900adbee 100644 (file)
@@ -75,7 +75,7 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) :
 
   // PPC/Linux normally uses named section for BSS.
   BSSSection_  = getNamedSection("\t.bss",
-                                 SectionFlags::Writeable | SectionFlags::BSS,
+                                 SectionFlags::Writable | SectionFlags::BSS,
                                  /* Override */ true);
 
   // Debug Information
index c13d45ceec7cf9ad209dc450cfe69b6f898388fb..0087c262fbd8668f3182e81a794c1d406b6df942 100644 (file)
@@ -28,7 +28,7 @@ SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM):
 
   // Sparc normally uses named section for BSS.
   BSSSection_  = getNamedSection("\t.bss",
-                                 SectionFlags::Writeable | SectionFlags::BSS,
+                                 SectionFlags::Writable | SectionFlags::BSS,
                                  /* Override */ true);
 }
 
@@ -41,7 +41,7 @@ std::string SparcELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
     Flags += ",#alloc";
   if (flags & SectionFlags::Code)
     Flags += ",#execinstr";
-  if (flags & SectionFlags::Writeable)
+  if (flags & SectionFlags::Writable)
     Flags += ",#write";
   if (flags & SectionFlags::TLS)
     Flags += ",#tls";
index dfb274f60845bdc4dd70a5546392a80fcb35152f..0a4c1b400e3804cbe401adf9ef90de7e5519831a 100644 (file)
@@ -122,7 +122,7 @@ TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) : TM(tm) {
   DwarfExceptionSection = ".gcc_except_table";
   AsmTransCBE = 0;
   TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
-  DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
+  DataSection = getUnnamedSection("\t.data", SectionFlags::Writable);
 }
 
 TargetAsmInfo::~TargetAsmInfo() {
@@ -160,9 +160,22 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
 }
 
 static bool isSuitableForBSS(const GlobalVariable *GV) {
-  // Leave constant zeros in readonly constant sections, so they can be shared
   Constant *C = GV->getInitializer();
-  return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
+  
+  // Must have zero initializer.
+  if (!C->isNullValue())
+    return false;
+  
+  // Leave constant zeros in readonly constant sections, so they can be shared.
+  if (GV->isConstant())
+    return false;
+  
+  // If the global has an explicit section specified, don't put it in BSS.
+  if (!GV->getSection().empty())
+    return false;
+  
+  // Otherwise, put it in BSS unless the target really doesn't want us to.
+  return !NoZerosInBSS;
 }
 
 static bool isConstantString(const Constant *C) {
@@ -183,36 +196,18 @@ static bool isConstantString(const Constant *C) {
 
 static unsigned SectionFlagsForGlobal(const GlobalValue *GV,
                                       SectionKind::Kind Kind) {
+  // Decode flags from global and section kind.
   unsigned Flags = SectionFlags::None;
-
-  // Decode flags from global itself.
-  switch (Kind) {
-  case SectionKind::Text:
-    Flags |= SectionFlags::Code;
-    break;
-  case SectionKind::ThreadData:
-  case SectionKind::ThreadBSS:
-    Flags |= SectionFlags::TLS;
-    // FALLS THROUGH
-  case SectionKind::Data:
-  case SectionKind::DataRel:
-  case SectionKind::DataRelLocal:
-  case SectionKind::DataRelRO:
-  case SectionKind::DataRelROLocal:
-  case SectionKind::BSS:
-    Flags |= SectionFlags::Writeable;
-    break;
-  case SectionKind::ROData:
-  case SectionKind::RODataMergeStr:
-  case SectionKind::RODataMergeConst:
-    // No additional flags here
-    break;
-  default:
-    llvm_unreachable("Unexpected section kind!");
-  }
-
   if (GV->isWeakForLinker())
     Flags |= SectionFlags::Linkonce;
+  if (SectionKind::isBSS(Kind))
+    Flags |= SectionFlags::BSS;
+  if (SectionKind::isTLS(Kind))
+    Flags |= SectionFlags::TLS;
+  if (SectionKind::isCode(Kind))
+    Flags |= SectionFlags::Code;
+  if (SectionKind::isWritable(Kind))
+    Flags |= SectionFlags::Writable;
 
   return Flags;
 }
@@ -331,11 +326,6 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
 
       // FIXME: Use mangler interface (PR4584).
       std::string Name = Prefix+GV->getNameStr();
-      
-      // Pick up the flags for the uniquing section.
-      // FIXME: HACK.
-      Flags |= getFlagsForNamedSection(Name.c_str());
-
       return getNamedSection(Name.c_str(), Flags);
     }
   }
@@ -348,10 +338,10 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
 const Section*
 TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
                                       SectionKind::Kind Kind) const {
-  if (Kind == SectionKind::Text)
+  if (SectionKind::isCode(Kind))
     return getTextSection();
   
-  if (Kind == SectionKind::BSS)
+  if (SectionKind::isBSS(SectionKind::BSS))
     if (const Section *S = getBSSSection_())
       return S;
   
@@ -374,27 +364,6 @@ TargetAsmInfo::getSectionForMergableConstant(uint64_t Size,
 }
 
 
-
-
-const char *
-TargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
-  switch (Kind) {
-  default: llvm_unreachable("Unknown section kind");
-  case SectionKind::Text:             return ".gnu.linkonce.t.";
-  case SectionKind::Data:             return ".gnu.linkonce.d.";
-  case SectionKind::DataRel:          return ".gnu.linkonce.d.rel.";
-  case SectionKind::DataRelLocal:     return ".gnu.linkonce.d.rel.local.";
-  case SectionKind::DataRelRO:        return ".gnu.linkonce.d.rel.ro.";
-  case SectionKind::DataRelROLocal:   return ".gnu.linkonce.d.rel.ro.local.";
-  case SectionKind::BSS:              return ".gnu.linkonce.b.";
-  case SectionKind::ROData:
-  case SectionKind::RODataMergeConst:
-  case SectionKind::RODataMergeStr:   return ".gnu.linkonce.r.";
-  case SectionKind::ThreadData:       return ".gnu.linkonce.td.";
-  case SectionKind::ThreadBSS:        return ".gnu.linkonce.tb.";
-  }
-}
-
 const Section *TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
                                               bool Override) const {
   Section &S = Sections[Name];
index 3dc7ec4b4fa7172e5424d9fc7535f94b87af7157..e71cd70a3d15836df801049d6c7ac32ae2925133 100644 (file)
@@ -282,7 +282,6 @@ getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
   case SectionKind::RODataMergeConst:
   case SectionKind::RODataMergeStr:   return ".rdata$linkonce";
   }
-  return NULL;
 }
 
 std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
@@ -290,7 +289,7 @@ std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
 
   if (flags & SectionFlags::Code)
     Flags += 'x';
-  if (flags & SectionFlags::Writeable)
+  if (flags & SectionFlags::Writable)
     Flags += 'w';
 
   Flags += "\"";
@@ -322,7 +321,7 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
   AlignmentIsInBytes = true;
 
   TextSection = getUnnamedSection("_text", SectionFlags::Code);
-  DataSection = getUnnamedSection("_data", SectionFlags::Writeable);
+  DataSection = getUnnamedSection("_data", SectionFlags::Writable);
 
   JumpTableDataSection = NULL;
   SwitchToSectionDirective = "";
index 6fc6dc2c7b3e323aaf6bc4e8b76eb53da3f0d4e1..9f6727b9c073eedc909ca60b7c928612af7bc718 100644 (file)
@@ -25,8 +25,8 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
   : ELFTargetAsmInfo(TM) {
   SupportsDebugInformation = true;
   TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
-  DataSection = getNamedSection("\t.dp.data", SectionFlags::Writeable);
-  BSSSection_  = getNamedSection("\t.dp.bss", SectionFlags::Writeable |
+  DataSection = getNamedSection("\t.dp.data", SectionFlags::Writable);
+  BSSSection_  = getNamedSection("\t.dp.bss", SectionFlags::Writable |
                                  SectionFlags::BSS);
 
   // TLS globals are lowered in the backend to arrays indexed by the current
@@ -36,7 +36,7 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
   TLSBSSSection = BSSSection_;
 
   if (TM.getSubtargetImpl()->isXS1A())
-    ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writeable);
+    ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writable);
   else
     ReadOnlySection = getNamedSection("\t.cp.rodata", SectionFlags::None);
   Data16bitsDirective = "\t.short\t";