diff options
author | Chris Lattner <sabre@nondot.org> | 2010-01-19 02:09:44 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-01-19 02:09:44 +0000 |
commit | aac138e84dee1cb3ffc1035b2a1e4361fe0b4f80 (patch) | |
tree | f62498c8c571448790a13d39837f8691fd77e21f /lib/Target | |
parent | 60a17740b845565f664e81a91b7019a520af88d7 (diff) |
Cleanup handling of .zerofill on darwin:
1. TargetLoweringObjectFileMachO should decide if something
goes in zerofill instead of having every target do it.
2. TargetLoweringObjectFileMachO should assign said symbols to
the right MCSection, the asmprinters should just emit to the
right section.
3. Since all zerofill stuff goes through mcstreamer anymore,
MAI can have a bool "haszerofill" instead of having the textual
directive to emit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93838 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 109 | ||||
-rw-r--r-- | lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 61 | ||||
-rw-r--r-- | lib/Target/TargetLoweringObjectFile.cpp | 8 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 127 |
4 files changed, 162 insertions, 143 deletions
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index ef2d460fab..30f9fec867 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -1196,71 +1196,76 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { if (Subtarget->isTargetELF()) O << "\t.type " << *GVarSym << ",%object\n"; + SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); const MCSection *TheSection = - getObjFileLowering().SectionForGlobal(GVar, Mang, TM); + getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); OutStreamer.SwitchSection(TheSection); + // Handle the zerofill directive on darwin, which is a special form of BSS + // emission. + if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) { + TargetLoweringObjectFileMachO &TLOFMacho = + static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); + if (TheSection == TLOFMacho.getDataCommonSection()) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); + // .zerofill __DATA, __common, _foo, 400, 5 + OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align); + return; + } + } + // FIXME: get this stuff from section kind flags. if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() && // Don't put things that should go in the cstring section into "comm". - !TheSection->getKind().isMergeableCString()) { - if (GVar->hasExternalLinkage()) { - if (const char *Directive = MAI->getZeroFillDirective()) { - O << "\t.globl\t" << *GVarSym << "\n"; - O << Directive << "__DATA, __common, " << *GVarSym - << ", " << Size << ", " << Align << "\n"; - return; - } - } + !TheSection->getKind().isMergeableCString() && + (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (isDarwin) { - if (GVar->hasLocalLinkage()) { - O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size - << ',' << Align; - } else if (GVar->hasCommonLinkage()) { - O << MAI->getCOMMDirective() << *GVarSym << ',' << Size - << ',' << Align; - } else { - OutStreamer.SwitchSection(TheSection); - O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective(); - O << *GVarSym << '\n'; - EmitAlignment(Align, GVar); - O << *GVarSym << ":"; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); - } - O << '\n'; - EmitGlobalConstant(C); - return; - } - } else if (MAI->getLCOMMDirective() != NULL) { - if (GVar->hasLocalLinkage()) { - O << MAI->getLCOMMDirective() << *GVarSym << "," << Size; - } else { - O << MAI->getCOMMDirective() << *GVarSym << "," << Size; - if (MAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + if (isDarwin) { + if (GVar->hasLocalLinkage()) { + O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size + << ',' << Align; + } else if (GVar->hasCommonLinkage()) { + O << MAI->getCOMMDirective() << *GVarSym << ',' << Size + << ',' << Align; + } else { + OutStreamer.SwitchSection(TheSection); + O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective(); + O << *GVarSym << '\n'; + EmitAlignment(Align, GVar); + O << *GVarSym << ":"; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } + O << '\n'; + EmitGlobalConstant(C); + return; + } + } else if (MAI->getLCOMMDirective() != NULL) { + if (GVar->hasLocalLinkage()) { + O << MAI->getLCOMMDirective() << *GVarSym << "," << Size; } else { - if (GVar->hasLocalLinkage()) - O << "\t.local\t" << *GVarSym << '\n'; O << MAI->getCOMMDirective() << *GVarSym << "," << Size; if (MAI->getCOMMDirectiveTakesAlignment()) - O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); + O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); } - O << "\n"; - return; + } else { + if (GVar->hasLocalLinkage()) + O << "\t.local\t" << *GVarSym << '\n'; + O << MAI->getCOMMDirective() << *GVarSym << "," << Size; + if (MAI->getCOMMDirectiveTakesAlignment()) + O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + } + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } + O << "\n"; + return; } switch (GVar->getLinkage()) { diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index db37a1ab66..fad1c27fac 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -721,25 +721,25 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { !GVar->hasSection() && (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() || GVar->isWeakForLinker())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (GVar->hasExternalLinkage()) { - O << "\t.global " << *GVarSym << '\n'; - O << "\t.type " << *GVarSym << ", @object\n"; - O << *GVarSym << ":\n"; - O << "\t.zero " << Size << '\n'; - } else if (GVar->hasLocalLinkage()) { - O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size; - } else { - O << ".comm " << *GVarSym << ',' << Size; - } - if (VerboseAsm) { - O << "\t\t" << MAI->getCommentString() << " '"; - WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); - O << "'"; - } - O << '\n'; - return; + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (GVar->hasExternalLinkage()) { + O << "\t.global " << *GVarSym << '\n'; + O << "\t.type " << *GVarSym << ", @object\n"; + O << *GVarSym << ":\n"; + O << "\t.zero " << Size << '\n'; + } else if (GVar->hasLocalLinkage()) { + O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size; + } else { + O << ".comm " << *GVarSym << ',' << Size; + } + if (VerboseAsm) { + O << "\t\t" << MAI->getCommentString() << " '"; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); + O << "'"; + } + O << '\n'; + return; } switch (GVar->getLinkage()) { @@ -944,10 +944,25 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); + SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); const MCSection *TheSection = - getObjFileLowering().SectionForGlobal(GVar, Mang, TM); + getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); OutStreamer.SwitchSection(TheSection); + // Handle the zerofill directive on darwin, which is a special form of BSS + // emission. + if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) { + TargetLoweringObjectFileMachO &TLOFMacho = + static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); + if (TheSection == TLOFMacho.getDataCommonSection()) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); + // .zerofill __DATA, __common, _foo, 400, 5 + OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align); + return; + } + } + /// FIXME: Drive this off the section! if (C->isNullValue() && /* FIXME: Verify correct */ !GVar->hasSection() && @@ -957,11 +972,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { !TheSection->getKind().isMergeableCString()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - if (GVar->hasExternalLinkage()) { - O << "\t.globl " << *GVarSym << '\n'; - O << "\t.zerofill __DATA, __common, " << *GVarSym << ", " - << Size << ", " << Align; - } else if (GVar->hasLocalLinkage()) { + if (GVar->hasLocalLinkage()) { O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align; } else if (!GVar->hasCommonLinkage()) { O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective(); diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 93cb420d62..26a181aea0 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -750,6 +750,9 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, ConstDataCoalSection = getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED, SectionKind::getText()); + DataCommonSection + = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL, + SectionKind::getBSS()); ConstDataSection // .const_data = getMachOSection("__DATA", "__const", 0, SectionKind::getReadOnlyWithRel()); @@ -915,6 +918,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, if (Kind.isReadOnlyWithRel()) return ConstDataSection; + // Put zero initialized globals with strong external linkage in the + // DATA, __common section with the .zerofill directive. + if (Kind.isBSS() && GV->hasExternalLinkage()) + return DataCommonSection; + // Otherwise, just drop the variable in the normal data section. return DataSection; } diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index a24a4f1746..3c290e8efd 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -664,88 +664,83 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { const TargetData *TD = TM.getTargetData(); - MCSymbol *GVSym = GetGlobalValueSymbol(GVar); + MCSymbol *GVarSym = GetGlobalValueSymbol(GVar); Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); - printVisibility(GVSym, GVar->getVisibility()); + printVisibility(GVarSym, GVar->getVisibility()); if (Subtarget->isTargetELF()) - O << "\t.type\t" << *GVSym << ",@object\n"; + O << "\t.type\t" << *GVarSym << ",@object\n"; SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); const MCSection *TheSection = getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); OutStreamer.SwitchSection(TheSection); + // Handle the zerofill directive on darwin, which is a special form of BSS + // emission. + if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) { + TargetLoweringObjectFileMachO &TLOFMacho = + static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); + if (TheSection == TLOFMacho.getDataCommonSection()) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); + // .zerofill __DATA, __common, _foo, 400, 5 + OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align); + return; + } + } + // FIXME: get this stuff from section kind flags. if (C->isNullValue() && !GVar->hasSection() && // Don't put things that should go in the cstring section into "comm". - !TheSection->getKind().isMergeableCString()) { - if (GVar->hasExternalLinkage()) { - if (MAI->hasZeroFillDirective()) { - // .globl _foo - OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global); - // .zerofill __DATA, __common, _foo, 400, 5 - TargetLoweringObjectFileMachO &TLOFMacho = - static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); - // FIXME: This stuff should already be handled by SectionForGlobal! - const MCSection *TheSection = - TLOFMacho.getMachOSection("__DATA", "__common", - MCSectionMachO::S_ZEROFILL, - SectionKind::getBSS()); - - OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << Align); - return; - } - } - - if (!GVar->isThreadLocal() && - (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (MAI->getLCOMMDirective() != NULL) { - if (GVar->hasLocalLinkage()) { - O << MAI->getLCOMMDirective() << *GVSym << ',' << Size; - if (Subtarget->isTargetDarwin()) - O << ',' << Align; - } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) { - OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global); - O << MAI->getWeakDefDirective() << *GVSym << '\n'; - EmitAlignment(Align, GVar); - O << *GVSym << ":"; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); - } - O << '\n'; - EmitGlobalConstant(C); - return; - } else { - O << MAI->getCOMMDirective() << *GVSym << ',' << Size; - if (MAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + !TheSection->getKind().isMergeableCString() && + !GVar->isThreadLocal() && + (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (const char *LComm = MAI->getLCOMMDirective()) { + if (GVar->hasLocalLinkage()) { + O << LComm << *GVarSym << ',' << Size; + if (Subtarget->isTargetDarwin()) + O << ',' << Align; + } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) { + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); + O << MAI->getWeakDefDirective() << *GVarSym << '\n'; + EmitAlignment(Align, GVar); + O << *GVarSym << ":"; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } + O << '\n'; + EmitGlobalConstant(C); + return; } else { - if (!Subtarget->isTargetCygMing()) { - if (GVar->hasLocalLinkage()) - O << "\t.local\t" << *GVSym << '\n'; - } - O << MAI->getCOMMDirective() << *GVSym << ',' << Size; + O << MAI->getCOMMDirective() << *GVarSym << ',' << Size; if (MAI->getCOMMDirectiveTakesAlignment()) O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); } - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); + } else { + if (!Subtarget->isTargetCygMing()) { + if (GVar->hasLocalLinkage()) + O << "\t.local\t" << *GVarSym << '\n'; } - O << '\n'; - return; + O << MAI->getCOMMDirective() << *GVarSym << ',' << Size; + if (MAI->getCOMMDirectiveTakesAlignment()) + O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + } + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() << ' '; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } + O << '\n'; + return; } switch (GVar->getLinkage()) { @@ -756,13 +751,13 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { case GlobalValue::WeakODRLinkage: case GlobalValue::LinkerPrivateLinkage: if (Subtarget->isTargetDarwin()) { - OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global); - O << MAI->getWeakDefDirective() << *GVSym << '\n'; + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); + O << MAI->getWeakDefDirective() << *GVarSym << '\n'; } else if (Subtarget->isTargetCygMing()) { - OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global); + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); O << "\t.linkonce same_size\n"; } else - O << "\t.weak\t" << *GVSym << '\n'; + O << "\t.weak\t" << *GVarSym << '\n'; break; case GlobalValue::DLLExportLinkage: case GlobalValue::AppendingLinkage: @@ -770,7 +765,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { // their name or something. For now, just emit them as external. case GlobalValue::ExternalLinkage: // If external or appending, declare as a global symbol - OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global); + OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); break; case GlobalValue::PrivateLinkage: case GlobalValue::InternalLinkage: @@ -780,7 +775,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { } EmitAlignment(Align, GVar); - O << *GVSym << ":"; + O << *GVarSym << ":"; if (VerboseAsm){ O.PadToColumn(MAI->getCommentColumn()); O << MAI->getCommentString() << ' '; @@ -791,7 +786,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) { EmitGlobalConstant(C); if (MAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << *GVSym << ", " << Size << '\n'; + O << "\t.size\t" << *GVarSym << ", " << Size << '\n'; } void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { |