It's not legal to output a GV in a coalesced section if it's used in an ARM PIC relat...
authorEvan Cheng <evan.cheng@apple.com>
Fri, 8 Aug 2008 06:56:16 +0000 (06:56 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 8 Aug 2008 06:56:16 +0000 (06:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54519 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/DarwinTargetAsmInfo.h
include/llvm/Target/ELFTargetAsmInfo.h
include/llvm/Target/TargetAsmInfo.h
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/DarwinTargetAsmInfo.cpp
lib/Target/ELFTargetAsmInfo.cpp
lib/Target/Mips/MipsTargetAsmInfo.cpp
lib/Target/Mips/MipsTargetAsmInfo.h
lib/Target/TargetAsmInfo.cpp
test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll [new file with mode: 0644]

index 0ed9b387037c3407ad9d83af160964362843d285..3403f066159233e5a766dbf1b6cdcea56a79866b 100644 (file)
@@ -30,7 +30,8 @@ namespace llvm {
     const Section* DataCoalSection;
 
     explicit DarwinTargetAsmInfo(const TargetMachine &TM);
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
+    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
+                                                 bool NoCoalesce = false) const;
     virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
                                                SectionKind::Kind kind) const;
     const Section* MergeableConstSection(const GlobalVariable *GV) const;
index fe339f8e591c7b1f22758df90cf17d0a75da52a1..b8261ef1da5cdd9e402cac8d64359aa0aa1163c1 100644 (file)
@@ -26,7 +26,8 @@ namespace llvm {
   struct ELFTargetAsmInfo: public virtual TargetAsmInfo {
     explicit ELFTargetAsmInfo(const TargetMachine &TM);
 
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
+    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
+                                                 bool NoCoalesce = false) const;
     virtual std::string PrintSectionFlags(unsigned flags) const;
     const Section* MergeableConstSection(const GlobalVariable *GV) const;
     inline const Section* MergeableConstSection(const Type *Ty) const;
index 04e91cb38120948bd805bddc0246e0c5b22d7402..2fd1492c99237c7a5ee21a73ddf29396d0457381 100644 (file)
@@ -544,8 +544,10 @@ namespace llvm {
                           const char* name = NULL) const;
 
     /// SectionForGlobal - This hooks returns proper section name for given
-    /// global with all necessary flags and marks.
-    virtual std::string SectionForGlobal(const GlobalValue *GV) const;
+    /// global with all necessary flags and marks. If NoCoalesce is true,
+    /// do not use coalesced section.
+    virtual std::string SectionForGlobal(const GlobalValue *GV,
+                                         bool NoCoalesce = false) const;
 
     // Helper methods for SectionForGlobal
     virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
@@ -553,7 +555,8 @@ namespace llvm {
 
     virtual std::string PrintSectionFlags(unsigned flags) const { return ""; }
 
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
+    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
+                                                 bool NoCoalesce = false) const;
 
     virtual const Section* SelectSectionForMachineConst(const Type *Ty) const;
 
index 3b30f9c5a0dfdc65d6aac3d4c19e9b2ffc488905..420ccd0bcc982070e44114b6d468091af4cddac0 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Compiler.h"
@@ -65,14 +66,18 @@ namespace {
     typedef std::map<const Value *, unsigned> ValueMapTy;
     ValueMapTy NumberForBB;
 
-    /// Keeps the set of GlobalValues that require non-lazy-pointers for
-    /// indirect access.
+    /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
+    /// non-lazy-pointers for indirect access.
     std::set<std::string> GVNonLazyPtrs;
 
-    /// Keeps the set of external function GlobalAddresses that the asm
-    /// printer should generate stubs for.
+    /// FnStubs - Keeps the set of external function GlobalAddresses that the
+    /// asm printer should generate stubs for.
     std::set<std::string> FnStubs;
 
+    /// PCRelGVs - Keeps the set of GlobalValues used in pc relative
+    /// constantpool.
+    SmallPtrSet<const GlobalValue*, 8> PCRelGVs;
+
     /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
     bool InCPMode;
     
@@ -124,10 +129,12 @@ namespace {
     /// specified function body into.
     virtual std::string getSectionForFunction(const Function &F) const;
 
+    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
+    /// the .s file.
     virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
       printDataDirective(MCPV->getType());
 
-      ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
+      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
       GlobalValue *GV = ACPV->getGV();
       std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
       if (!GV)
@@ -680,9 +687,15 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
     const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
       MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
     
-    if (MCPE.isMachineConstantPoolEntry())
+    if (MCPE.isMachineConstantPoolEntry()) {
       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
-    else {
+      ARMConstantPoolValue *ACPV =
+        static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
+      if (ACPV->getPCAdjustment() != 0) {
+        const GlobalValue *GV = ACPV->getGV();
+        PCRelGVs.insert(GV);
+      }
+    } else {
       EmitGlobalConstant(MCPE.Val.ConstVal);
       // remember to emit the weak reference
       if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
@@ -850,7 +863,8 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     return;
   }
 
-  std::string SectionName = TAI->SectionForGlobal(GVar);
+  bool NoCoalesc = PCRelGVs.count(GVar);
+  std::string SectionName = TAI->SectionForGlobal(GVar, NoCoalesc);
   std::string name = Mang->getValueName(GVar);
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
@@ -887,7 +901,7 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
       if (TAI->getLCOMMDirective() != NULL) {
-        if (GVar->hasInternalLinkage()) {
+        if (NoCoalesc || GVar->hasInternalLinkage()) {
           O << TAI->getLCOMMDirective() << name << "," << Size;
           if (Subtarget->isTargetDarwin())
             O << "," << Align;
index 749cb7179437c8e9c0329f9c881a10fd8254834e..978f5cf36ac15c5672534d50bc7315168456ba0e 100644 (file)
@@ -51,14 +51,15 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) {
 }
 
 const Section*
-DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
+DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
+                                            bool NoCoalesce) const {
   SectionKind::Kind Kind = SectionKindForGlobal(GV);
-  bool isWeak = GV->isWeakForLinker();
+  bool CanCoalesce = !NoCoalesce && GV->isWeakForLinker();
   bool isNonStatic = (DTM->getRelocationModel() != Reloc::Static);
 
   switch (Kind) {
    case SectionKind::Text:
-    if (isWeak)
+    if (CanCoalesce)
       return TextCoalSection;
     else
       return getTextSection_();
@@ -67,18 +68,18 @@ DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
    case SectionKind::BSS:
    case SectionKind::ThreadBSS:
     if (cast<GlobalVariable>(GV)->isConstant())
-      return (isWeak ? ConstDataCoalSection : ConstDataSection);
+      return (CanCoalesce ? ConstDataCoalSection : ConstDataSection);
     else
-      return (isWeak ? DataCoalSection : getDataSection_());
+      return (CanCoalesce ? DataCoalSection : getDataSection_());
    case SectionKind::ROData:
-    return (isWeak ? ConstDataCoalSection :
+    return (CanCoalesce ? ConstDataCoalSection :
             (isNonStatic ? ConstDataSection : getReadOnlySection_()));
    case SectionKind::RODataMergeStr:
-    return (isWeak ?
+    return (CanCoalesce ?
             ConstDataCoalSection :
             MergeableStringSection(cast<GlobalVariable>(GV)));
    case SectionKind::RODataMergeConst:
-    return (isWeak ?
+    return (CanCoalesce ?
             ConstDataCoalSection:
             MergeableConstSection(cast<GlobalVariable>(GV)));
    default:
index 82ac847e845fcb9e9d4f54ee35b202b77eb37878..523527c7b6d70438861513a326cef9b7fb7ad970 100644 (file)
@@ -40,7 +40,8 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) {
 }
 
 const Section*
-ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
+ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
+                                         bool NoCoalesce) const {
   SectionKind::Kind Kind = SectionKindForGlobal(GV);
 
   if (const Function *F = dyn_cast<Function>(GV)) {
index 04edd0d4b537c8031f08910dbae4ab9e922f2a71..eff69abc6db28c066254edbf051109537ee20d30 100644 (file)
@@ -82,7 +82,7 @@ SectionKindForGlobal(const GlobalValue *GV) const {
 }
 
 const Section* MipsTargetAsmInfo::
-SelectSectionForGlobal(const GlobalValue *GV) const {
+SelectSectionForGlobal(const GlobalValue *GV, bool NoCoalesce) const {
   SectionKind::Kind K = SectionKindForGlobal(GV);
   const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
 
index 2b5a739e7219ea9c271ed536a75a7b0058bfe577..806cda8be368ea338e444338887b6a026aa04e83 100644 (file)
@@ -40,7 +40,8 @@ namespace llvm {
     SectionFlagsForGlobal(const GlobalValue *GV = NULL,
                           const char* name = NULL) const;
 
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
+    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
+                                                  bool NoCoalesce) const;
 
     private:
       const MipsSubtarget *Subtarget;
index 9bc0b4055e3370bdddb54e18c58a8c19a3884139..cf43112634928ed78646e9075936da7d1c781351 100644 (file)
@@ -272,7 +272,7 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
 }
 
 std::string
-TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
+TargetAsmInfo::SectionForGlobal(const GlobalValue *GV, bool NoCoalesce) const {
   const Section* S;
   // Select section name
   if (GV->hasSection()) {
@@ -282,7 +282,7 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
     S = getNamedSection(GV->getSection().c_str(), Flags);
   } else {
     // Use default section depending on the 'type' of global
-    S = SelectSectionForGlobal(GV);
+    S = SelectSectionForGlobal(GV, NoCoalesce);
   }
 
   if (!S->isNamed())
@@ -295,8 +295,8 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
 }
 
 // Lame default implementation. Calculate the section name for global.
-const Section*
-TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
+const Section* TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
+                                                     bool NoCoalesce) const {
   SectionKind::Kind Kind = SectionKindForGlobal(GV);
 
   if (GV->isWeakForLinker()) {
diff --git a/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll b/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll
new file mode 100644 (file)
index 0000000..d2a8bb2
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -mattr=+v6 -relocation-model=pic | grep lcomm
+
+       %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+       %struct.__gcov_var = type { %struct.FILE*, i32, i32, i32, i32, i32, i32, [1025 x i32] }
+       %struct.__sFILEX = type opaque
+       %struct.__sbuf = type { i8*, i32 }
+@__gcov_var = common global %struct.__gcov_var zeroinitializer         ; <%struct.__gcov_var*> [#uses=1]
+
+define i32 @__gcov_close() nounwind {
+entry:
+       load i32* getelementptr (%struct.__gcov_var* @__gcov_var, i32 0, i32 5), align 4                ; <i32>:0 [#uses=1]
+       ret i32 %0
+}