summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-06-28 13:45:57 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-06-28 13:45:57 +0000
commit2e052a81fd806c90605abaef19f40feb54aa825c (patch)
tree4c554be8360d2690096287ca0534ff05e2155d13
parent3c21b05225e454a125dc37f69d01293d7a3203fb (diff)
downloadbcm5719-llvm-2e052a81fd806c90605abaef19f40feb54aa825c.tar.gz
bcm5719-llvm-2e052a81fd806c90605abaef19f40feb54aa825c.zip
Start refactoring of asmprinters: provide a TAI hook, which will select a 'section kind' for a global.
llvm-svn: 52868
-rw-r--r--llvm/include/llvm/Target/TargetAsmInfo.h22
-rw-r--r--llvm/lib/Target/TargetAsmInfo.cpp49
2 files changed, 69 insertions, 2 deletions
diff --git a/llvm/include/llvm/Target/TargetAsmInfo.h b/llvm/include/llvm/Target/TargetAsmInfo.h
index 9b5ba4819cb..3b16ef1645f 100644
--- a/llvm/include/llvm/Target/TargetAsmInfo.h
+++ b/llvm/include/llvm/Target/TargetAsmInfo.h
@@ -29,8 +29,22 @@ namespace llvm {
};
}
+ namespace SectionKind {
+ enum Kind {
+ Text, ///< Text section
+ Data, ///< Data section
+ BSS, ///< BSS section
+ ROData, ///< Readonly data section
+ RODataMergeStr, ///< Readonly data section (mergeable strings)
+ RODataMergeConst, ///< Readonly data section (mergeable constants)
+ ThreadData, ///< Initialized TLS data objects
+ ThreadBSS ///< Uninitialized TLS data objects
+ };
+ }
+
class TargetMachine;
class CallInst;
+ class GlobalValue;
/// TargetAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
@@ -427,7 +441,11 @@ namespace llvm {
/// if the symbol can be relocated.
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
bool Global) const;
-
+
+ /// SectionKindForGlobal - This hook allows the target to select proper
+ /// section kind used for global emission.
+ SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const;
+
// Accessors.
//
const char *getTextSection() const {
@@ -642,7 +660,7 @@ namespace llvm {
}
const char *getDwarfSectionOffsetDirective() const {
return DwarfSectionOffsetDirective;
- }
+ }
const char *getDwarfAbbrevSection() const {
return DwarfAbbrevSection;
}
diff --git a/llvm/lib/Target/TargetAsmInfo.cpp b/llvm/lib/Target/TargetAsmInfo.cpp
index 67f0cfa5be8..2adad3d7baa 100644
--- a/llvm/lib/Target/TargetAsmInfo.cpp
+++ b/llvm/lib/Target/TargetAsmInfo.cpp
@@ -12,7 +12,13 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Constants.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Function.h"
+#include "llvm/Module.h"
+#include "llvm/Type.h"
#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
#include <cctype>
#include <cstring>
@@ -142,3 +148,46 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
return dwarf::DW_EH_PE_absptr;
}
+static bool isSuitableForBSS(const GlobalVariable *GV) {
+ if (!GV->hasInitializer())
+ return true;
+
+ // Leave constant zeros in readonly constant sections, so they can be shared
+ Constant *C = GV->getInitializer();
+ return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
+}
+
+SectionKind::Kind
+TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
+ // Early exit - functions should be always in text sections.
+ if (isa<Function>(GV))
+ return SectionKind::Text;
+
+ const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
+ bool isThreadLocal = GVar->isThreadLocal();
+ assert(GVar && "Invalid global value for section selection");
+
+ SectionKind::Kind kind;
+ if (isSuitableForBSS(GVar)) {
+ // Variable can be easily put to BSS section.
+ return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS);
+ } else if (GVar->isConstant() && !isThreadLocal) {
+ // Now we know, that varible has initializer and it is constant. We need to
+ // check its initializer to decide, which section to output it into. Also
+ // note, there is no thread-local r/o section.
+ Constant *C = GVar->getInitializer();
+ if (C->ContainsRelocations())
+ kind = SectionKind::ROData;
+ else {
+ const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+ // Check, if initializer is a null-terminated string
+ if (CVA && CVA->isCString())
+ kind = SectionKind::RODataMergeStr;
+ else
+ kind = SectionKind::RODataMergeConst;
+ }
+ }
+
+ // Variable is not constant or thread-local - emit to generic data section.
+ return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data);
+}
OpenPOWER on IntegriCloud