summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/TargetAsmInfo.cpp
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 /llvm/lib/Target/TargetAsmInfo.cpp
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
Diffstat (limited to 'llvm/lib/Target/TargetAsmInfo.cpp')
-rw-r--r--llvm/lib/Target/TargetAsmInfo.cpp49
1 files changed, 49 insertions, 0 deletions
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