summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetMachine.h15
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp38
-rw-r--r--lib/Target/TargetMachine.cpp25
-rw-r--r--test/CodeGen/X86/global-sections.ll10
4 files changed, 85 insertions, 3 deletions
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index d1d665f870..6697b73f49 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -171,6 +171,21 @@ public:
/// is false.
static void setAsmVerbosityDefault(bool);
+ /// getDataSections - Return true if data objects should be emitted into their
+ /// own section, corresponds to -fdata-sections.
+ static bool getDataSections();
+
+ /// getFunctionSections - Return true if functions should be emitted into
+ /// their own section, corresponding to -ffunction-sections.
+ static bool getFunctionSections();
+
+ /// setDataSections - Set if the data are emit into separate sections.
+ static void setDataSections(bool);
+
+ /// setFunctionSections - Set if the functions are emit into separate
+ /// sections.
+ static void setFunctionSections(bool);
+
/// CodeGenFileType - These enums are meant to be passed into
/// addPassesToEmitFile to indicate what type of file to emit, and returned by
/// it to indicate what type of file could actually be made.
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index dc08cadaaa..9f959932e6 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -279,14 +279,48 @@ static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
return ".gnu.linkonce.d.rel.ro.";
}
+/// getSectionPrefixForGlobal - Return the section prefix name used by options
+/// FunctionsSections and DataSections.
+static const char *getSectionPrefixForGlobal(SectionKind Kind) {
+ if (Kind.isText()) return ".text.";
+ if (Kind.isReadOnly()) return ".rodata.";
+
+ if (Kind.isThreadData()) return ".tdata.";
+ if (Kind.isThreadBSS()) return ".tbss.";
+
+ if (Kind.isDataNoRel()) return ".data.";
+ if (Kind.isDataRelLocal()) return ".data.rel.local.";
+ if (Kind.isDataRel()) return ".data.rel.";
+ if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local.";
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return ".data.rel.ro.";
+}
+
+
const MCSection *TargetLoweringObjectFileELF::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
+ // If we have -ffunction-section or -fdata-section then we should emit the
+ // global value to a uniqued section specifically for it.
+ bool EmitUniquedSection;
+ if (Kind.isText())
+ EmitUniquedSection = TM.getFunctionSections();
+ else
+ EmitUniquedSection = TM.getDataSections();
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
- const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ if ((GV->isWeakForLinker() || EmitUniquedSection) &&
+ !Kind.isCommon() && !Kind.isBSS()) {
+ const char *Prefix;
+ if (GV->isWeakForLinker())
+ Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ else {
+ assert(EmitUniquedSection);
+ Prefix = getSectionPrefixForGlobal(Kind);
+ }
+
SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
MCSymbol *Sym = Mang->getSymbol(GV);
Name.append(Sym->getName().begin(), Sym->getName().end());
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index 88871e3580..871b148adb 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -197,7 +197,14 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim",
cl::desc("Use strong PHI elimination."),
cl::location(StrongPHIElim),
cl::init(false));
-
+static cl::opt<bool>
+DataSections("fdata-sections",
+ cl::desc("Emit data into separate sections"),
+ cl::init(false));
+static cl::opt<bool>
+FunctionSections("ffunction-sections",
+ cl::desc("Emit functions into separate sections"),
+ cl::init(false));
//---------------------------------------------------------------------------
// TargetMachine Class
//
@@ -244,6 +251,22 @@ void TargetMachine::setAsmVerbosityDefault(bool V) {
AsmVerbosityDefault = V;
}
+bool TargetMachine::getFunctionSections() {
+ return FunctionSections;
+}
+
+bool TargetMachine::getDataSections() {
+ return DataSections;
+}
+
+void TargetMachine::setFunctionSections(bool V) {
+ FunctionSections = V;
+}
+
+void TargetMachine::setDataSections(bool V) {
+ DataSections = V;
+}
+
namespace llvm {
/// LessPreciseFPMAD - This flag return true when -enable-fp-mad option
/// is specified on the command line. When this flag is off(default), the
diff --git a/test/CodeGen/X86/global-sections.ll b/test/CodeGen/X86/global-sections.ll
index d79c56bc46..732d764dbd 100644
--- a/test/CodeGen/X86/global-sections.ll
+++ b/test/CodeGen/X86/global-sections.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -mtriple=i386-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX
; RUN: llc < %s -mtriple=i386-apple-darwin9.7 | FileCheck %s -check-prefix=DARWIN
+; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -fdata-sections | FileCheck %s -check-prefix=LINUX-SECTIONS
; int G1;
@@ -32,6 +33,12 @@
; DARWIN: _G3:
; DARWIN: .long _G1
+; LINUX: .section .rodata,"a",@progbits
+; LINUX: .globl G3
+
+; LINUX-SECTIONS: .section .rodata.G3,"a",@progbits
+; LINUX-SECTIONS: .globl G3
+
; _Complex long long const G4 = 34;
@G4 = constant {i64,i64} { i64 34, i64 0 }
@@ -97,6 +104,9 @@
; LINUX: G7:
; LINUX: .asciz "abcdefghi"
+; LINUX-SECTIONS: .section .rodata.G7,"aMS",@progbits,1
+; LINUX-SECTIONS: .globl G7
+
@G8 = constant [4 x i16] [ i16 1, i16 2, i16 3, i16 0 ]