diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-28 13:45:57 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-06-28 13:45:57 +0000 |
commit | 2e052a81fd806c90605abaef19f40feb54aa825c (patch) | |
tree | 4c554be8360d2690096287ca0534ff05e2155d13 /llvm/lib/Target/TargetAsmInfo.cpp | |
parent | 3c21b05225e454a125dc37f69d01293d7a3203fb (diff) | |
download | bcm5719-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.cpp | 49 |
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); +} |